|
FDISK,系98的FDISK.EXE(>512M模式运行) PQMAGIC,系POWER QUEST公司的PQMAGIC.EXE(DOS版,7) 本文基于486DX2,主板,可带primary/secondary两IDE控制器,中断14/15,每个IDE,可带master,slave两通道,每个通道,可带1台硬盘驱动器,每台驱动器,可带1块NORMAL,LBA,LARGE模式的IDE硬盘. DOS,98对硬盘,先按IDE,后按master/slave,依次编号,不编闲置通道.例如,有3块盘,块1,2在primary的master/slave上,块3在secondary的slave上,此3块,编为80h~82h. 开机盘的IDE及通道,由BIOS的BOOT SEQUENCE指定. (1) DOS/98的读写FAT 16/32格式的位置X的Y个连续扇区的BIOS中断13h参数: ah的2/3指明读/写,al的低6位指明Y,es:bx指向内存buf首,cl的低6位指明X的扇号sector,最小值1,ch的8位,左拼cl第6,7位,齐指X的柱面号cylinder,最小值0,dh指明磁头号head,最小值0,dl指明软硬盘编号. NORMAL,柱面数1024,磁头数16,扇区数63,每扇512字节,相乘=容量528MB.用作chs(cylinder,head,sector)立体寻扇及98挂大盘 LBA,磁头异数到255,容量8.4GB LARGE,盘柱面数>1024,磁头数16时,控制器做柱面数/2,磁头数*2,以调13h.容量1G (2) 针对LBA的扩展13h线性64位lba寻扇: chs转成lba的公式:lba=c*sectors_per_cylinder+h*sectors_per_track+(s-1) 其中,sectors_per_cylinder为每柱面扇数,sectors_per_track为每磁道扇数,因s从1编号,要减1. chs,lba的互转,见"(7) prw文"的chs2lba,lba2chs. 利用extblk块: extblk db 16 ;块的字节数(包括此字节) rsv db 0 ;需为0 sec_tot dw 1 ;指明Y个扇区 buf_off dw 0 ;内存buf偏移 buf_seg dw 0 ;内存buf段值 lbal dw 0 ;lba低双字低字 lbah dw 0 ;lba低双字高字 dd 0 ;lba高双字 读/写时,ah=42h/43h,ds:si指向extblk,dl意义不变 扩展i13接口的BIOS支持及导出硬盘柱面数,磁头数,每磁道扇区数,算法见"(7) prw文"的h_geo (3) 硬盘分区: 每块硬盘,最多划为DOS主分区,DOS扩展分区,非DOS分区之1的4分区,述于16字节分区表: bootON db 0 80h/00,指明活跃/不活跃.MBR交控制给驻有OS的活跃主分区引导记录 db ? 指明启动头号 dw ? 低6位指明启动扇区,高字节的8位,左拼低字节第6,7位,齐指启动柱面号 volume db 0 分区标识值 db ? 指明结束头号 dw ? 低6位指明结束扇区,高字节的8位,左拼低字节第6,7位,齐指结束柱面号 Front dd 0 此分区之前扇区数,低/高字在前/后,如10025009H,5009在前 In dd 0 此分区所含扇区数,低/高字在前/后 分区标识值: 闲置:0 DOS主分区:1,4,6,0bh,0ch,0eh DOS扩展分区:5,0fh 非DOS分区:其它 笔者用P,对硬盘划分4个DOS主分区,再用prw,读此盘chs(0:0:0)到文件0,用debug,改分区volume值为2,用prw,回写0到chs(0:0:0),P的分区info页,显出volume对应FAT类型XENIX.再得 对应意义,见"(7) prw 文"的FAT 若volume<20H,则高4位,1/0表示隐藏/非隐藏,后缀X,用于扩展i13接口. 各硬盘,均含称为主引导记录(MBR)的1个扇,位于chs第0头第0柱面第1扇,其偏移1be字节,连续存4个分区表. 各硬盘,最多1个DOS扩展分区,其内,能划分称为逻辑分区的数个DOS主分区,非DOS分区. 逻辑分区串成链.例如,volume为5的扩展分区E,先含1个DOS主分区D,后含1个非DOS分区N,则E的Front域值F,是E内的各逻辑分区位置基址,F指明扇区S1,而S1的偏移1be字节,是D的分区表,偏移1ce字节,其volume为0fh,表明是DOS扩展分区,其Front域值,加上基址F,指明扇区S2,而S2的偏移1be字节,是N的分区表,偏移1ce字节,其volume为链尾0. (4) 仿F及P,列出分区逻辑盘符: 盘符,从C:列向Z:.用F及P,能建数个逻辑分区 分区超过Z:符时,F照列,P不赋盘符,prw赋^符 活跃区数>1时,F,prw照列,P显错,boot失败 F及P,依volume域,查以下3步,每步,查80h至83h: (1) 查DOS主分区 分区若是DOS主分区,则查活跃值bootON是否80H,若是,此分区就占1个逻辑盘符,若无活跃主分区,表项在MBR首现的主分区,就占1个逻辑盘符. 例如,80h~82h硬盘,80h的第1,3分区是主分区,但第3分区活跃,则第3分区占盘符C:.而81h,只含DOS扩展分区,其上,含1个DOS主分区及1个非DOS分区;82h的第2,4分区是不活跃主分区,则最先在MBR中出现的第2分区,占盘符D: (2) 查DOS扩展分区 按逻辑分区在链上次序,查它是否DOS主分区,是就占盘符,81h的DOS扩展分区上的DOS主分区,占盘符E: (3) 查未占过盘符的DOS主分区及非DOS分区 按MBR中,分区表项出现的先后次序,查分区是否DOS主分区,若是,且它未占过盘符,就占盘符.80h的第1分区,占盘符F:,82h的第4分区,占盘符G: F,P,prw,不给非DOS分区赋盘符,仅显出从In得的容量. (5) 例: 笔者机器,在primary master上,装ST32140A驱动器(2012M),在secondary master上,装QUANTUM MAVERICK 540A驱动器(514M). (5.1) 80h上,现有volume为6的活跃主分区(FAT16B,1299M),volume为6的DOS主分区(FAT16B,39.4M),volume为17h的非DOS分区(HiddenNTFS,574.9M),volume为5的扩展分区,其上,有4个逻辑分区,按链上次序是: volume为0bh的DOS主分区(FAT32,35.4M,簇xk),volume为83h的非DOS分区(Linux_Ext2,19.7M),volume为1的DOS主分区(Unformatted,3.9M),volume为6的DOS主分区(FAT16B,41.3M), (5.2) 81h上,现有volume为82h的非DOS分区(Linux_Swap,3M),volume为11h的非DOS分区(Unformatted,3M),volume为6的活跃主分区(FAT16B,472.5M),volume为0fh的扩展分区,其上,有4个逻辑分区,按链上次序: volume为82h的非DOS分区(Linux_Swap,10.8M),volume为1的DOS主分区(FAT12,8.8M),volume为7的非DOS分区(NTFS,9,8M),volume为1的DOS主分区(Unformatted,7.8M). 用98启动盘开机,F,P,prw,对这些分区,列出盘符及容量(MB:...是prw的16进制列出) C:1299M(MB:00000513) D;472.5M(MB:000001d9) E:35.4M(MB:00000023) F:3.9M(MB:00000004) G:41.3M(MB:00000029) J:39.4M(MB:00000027) H:8.8M(MB:00000009) I:7.8M(MB:00000008) (6) prw功能 命令行格式为prw.exe [foo],foo为当前目录下文件名. 初始界面: p(artition),r(ead sec to cmdline_file/stdout),w(rite file to sec),v(xd w) 按p,r,w,v键,启动命令: (6.1) 命令p,显出如下值:分区硬盘编号(80),逻辑盘符(C:),BootON值(80),volume值(06),Front值(3f),In值(3ee041),从In得的容量(7dc): 80,C:,Boot(80),FAT(06),Front|In:0000003f|003ee041,MB:000007dc p无限显示,则存失效F的扩展分区递归的硬盘锁. (6.2) 命令r,读软硬盘内容到新建file,或scr (6.3) 命令wv,写已存file到软硬盘,但v,依C.VxD,克服9x的DOS窗口保护硬盘,不许13h写之劣.算法见"(8) 论9x的V86下,直寻硬盘扇区,只能靠VxD" 命令r/w/v,可用c(hs),l(ba),寻源FAT16或v86的FAT32扇,最多ffff扇,出错时,部分扇区被写入文件. 对命令r,扇区从磁盘读到buf而写file/scr前,对wv,扇区从file读到buf而写磁盘前,屏幕上方,显出正处理的扇区计数及buf十六进制值,下方,显出"ctl_c,g(o),q(uiet),",用户按ctl_c键,就异常结束,按'q'键,就不再显buf. 欲读80h的MBR到文件0,可发: prw 0 命令r界面及回答: drv(00~01,80~83)80 0~cyl(03fd) 0~hd(3f) 1~sec(3f) 0~lba(003ee07f) c(hs),l(ba)l 0~lba(003ee07f)00000000 0~cyl(0000) 0~hd(00) 1~sec(01) 0~lba(00000000) 1~total(ffff)0001 正常/异常结束,文件0长度=512/0. (7) prw文 NIBSZ=8 ;8个hex数 nibasc macro local nibasc0 add al,48 cmp al,10+48 jb nibasc0 add al,97-48-10 nibasc0: endm alasc macro mov ah,al and al,15 nibasc xchg ah,al rept 4 shr al,1 高nibble endm nibasc stosw endm axasc macro xchg ah,al 转ah push ax alasc pop ax xchg ah,al 转al alasc endm d segment buf db 511 dup(0) 放硬盘MRB.全囿V86页(4k),buf长1023 buf511 db 0 老buf尾 info_sz dw 26 ;minimal size of information buffer 新buf flags dw 0 ;information flags cylinders0 dw 0 ;number of cylinders on disk cylinders1 dw 0 heads00 db 0 ;number of heads on disk heads01 db 0 heads1 dw 0 s1track00 db 0 ;number of sectors per track s1track01 db 0 s1track1 dw 0 sectors dq 0 ;number of sectors on requested disk sector_sz dw 0 ;number of bytes per sector db 511-26 dup(0) ;新buf FAT db 13,10,13,10,'0~0fh:',13,10 db 'Noknown,FAT12/Unformatted,XENIX,XENIX2,FAT16/U_,Extended,FAT16B,NTFS,AIX or Coherent,AIX SplitDrive,Boot Manager,FAT32,FAT32X,Type 0D,FAT16,E_X',13,10 db 13,10,'11,14,16,17,1b:',13,10 db 'HiddenFAT12/U_,H_FAT16,H_FAT16B,H_NTFS,H_FAT32',13, 10 db 13,10,'65,82,83:',13,10 db 'Netware,Linux_Swap,Linux_Ext2',13,10,36 extblk db 16 分区表16字节用 rsv db 0 sec_tot dw 1 buf_off dw buf ;buf偏移 buf_seg dw SEG buf lbal dw 0 ;lba低双字低字 lbah dw 0 ;lba低双字高字 dd 0 ;lba高双字 cmd_p db 'p(artition),r(ead sec to cmdline_file/stdout),w(rite file to sec),v(xd w)$';rwv用 drv_p db 13,10,'drv(00~01,80~83)$' ;扩展i13用 mod_p db 13,10,'c(hs),l(ba)$' ;dosext,nondos用 .from80 dw 0d0ah from80 db '80,' 读扇到file logidrv db 'C:,Boot(' Boot db '00),FAT(' volume db '06),Front|In:' Front_h dw ?,? 又做总扇数 Front_l db '0000|' In_h dw ?,? 又做当前扇号 In_l db '0000,MB:' MB db '00200000',13,10,36 cyl_p db 2 dup(13,10),'0~cyl(' cyl_p1 db '????)$' hd_p db 13,10,'0~hd(' hd_p1 db '??)$' sec_p db 13,10,'1~sec(' sec_p1 db '??)$' lba_p db 13,10,'0~lba(' lbah_p1 db '????' lbal_p1 db '????)$' total_p db 13,10,'1~total(ffff)$' scr_p db 'ctl_c,g(o),q(uiet)$' ;显当前扇号 primk db 1,4,6,11,12,14 主分区标识 primksz=$-primk extmk db 5,15 扩展分区标识 extmksz=$-extmk stk1 dw NIBSZ/4 dup(0) ;INnib栈 db 32 rowasc db (2+1)*15+2 dup(32),13,10,36 kbd db NIBSZ+1 ;键盘buf kbd1 db 67 parti用 kbd2 db NIBSZ+1 dup(0) fcbdrv db 0 fcbnam db 8 dup(32) fcbext db 3 dup(32) fcbblk dw 0 fcbrsz dw 512 fcbsz db 4 dup (4) 已占分区表号,4硬盘*1字节,parti用 fcbdat dw 0 fcbdos1 db 10 dup(0) fcbrno db 0 entry label dword ;fcbrand entrydi dw 0 entryes dw 0 media_h db 0 ;介质头数 media_c dw 0 ;柱面数 s1cyl dw 0 ;每柱面扇数 s1track db 0 ;每道扇数 drv db 0 ;输入值 hd db 0 cyl dw 0 sec db 0 hextbl db '0123456789abcdef' d ends c segment assume es:d,cs:c,ss:d,ds:d @ proc far push ds ;为exe返回 xor ax,ax push ax cld mov bx,d mov es,bx 置es mov si,5ch sh,复制盘符,8.3名到5ch,功能create/open,拒认.3 cmp byte ptr [si+1],32 jne @1 mov es:from80,al 未点file jmp @2 @1: lea di,fcbdrv mov cx,1 + 8 + 3 ;ds:si的盘符及大写8.3,送es:di rep movsb @2: mov ds,bx 置ds mov ah,9 lea dx,cmd_p ;问命令 int 21h mov ah,1 int 21h cmp al,'p' jne r mov ah,9 lea dx,FAT int 21h lea bx,buf mov dx,80h 扩展i13,可兼容传统 Call dospri mov mod_p,dl mov dl,80h Call dosext mov lbal,0 mov lbah,0 mov dl,80h Call nondos ret r: mov cmd_p,al cmp al,'r' je rwv cmp al,'w' je rwv cmp al,'v' je v ret v: mov ax,1684h ;func mov bx,3180h ;接口ID int 2fh mov ax,es ;es:di=V86口cs:ip or ax,di jnz v1 ret es,di全0,失败 v1: mov entrydi,di mov entryes,es mov ax,ds ;置es mov es,ax rwv: mov kbd,2 + 1 lea dx,drv_p 问磁盘 Call INnib mov drv,bl mov dl,bl 驱动器 test bl,80h jne rwv1 xor dh,dh 头 Call f_geo jmp rwv2 rwv1: Call h_geo rwv2: test media_h,255 jne rwv3 ret rwv3: mul s1cyl sub ax,1 ;lba始于0 sbb dx,0 mov lbal,ax mov lbah,dx Call lba2chs Call rng mov ah,9 ;问寻扇 lea dx,mod_p int 21h mov ah,1 int 21h cmp al,'c' je rwv4 mov kbd,8 + 1 lea dx,lba_p call INnib ;问lbah,lbal mov lbal,bx mov ax,stk1 mov lbah,ax Call lba2chs jmp rwv5 rwv4:mov kbd,4 + 1 lea dx,cyl_p ;问柱面号 Call INnib mov cyl,bx mov kbd,2 + 1 lea dx,hd_p ;问头号 Call INnib mov hd,bl mov kbd,2 + 1 lea dx,sec_p ;问扇号 Call INnib mov sec,bl Call chs2lba rwv5:Call rng ;显出立体,线性值 mov kbd,4 + 1 lea dx,total_p ;问总计 Call INnib mov Front_h,bx lea dx,fcbdrv ;指向fcb mov ah,15 ;open for w,v cmp cmd_p,'r' jne rw1 test from80,255 ;判读入file jz rw2 mov ah,16h ;create or trunc for r rw1: int 21h 改fcbdrv为3=C or al,al al为0,成功 jnz rw8 mov fcbrsz,512 重置 rw2: mov ah,1ah ;DTA lea dx,buf mov bx,dx ;内存数据区 int 21h rw3: test Front_h,65535 jz rw6 cmp cmd_p,'r' jne rw4 mov ax,201h mov dl,drv Call rw1sec jc rw6 Call scr test from80,255 ;判读入file jz rw5 mov ah,15h ;强行write lea dx,fcbdrv int 21h jmp rw5 rw4: mov ah,14h ;read lea dx,fcbdrv int 21h Call scr mov ax,301h mov dl,drv Call rw1sec jc rw7 ;出错,关闭 rw5: Add lbal,1 adc lbah,0 inc In_h dec Front_h jmp rw3 rw6: test from80,255 ;判读入file jz rw8 rw7: mov ah,16 ;close lea dx,fcbdrv int 21h rw8: ret @ endp dospri proc ;统计硬盘数,查DOS主分区 dospri0:cmp dl,80h+4 je dospri7 mov ax,201h ;测硬盘 mov cx,1 int 13h jc dospri7 mov bp,4*16 xor si,si ;分区表,占4*16字节 dospri1:cmp si,4*16 je dospri4 mov al,buf[1beh+si+4] 取volume mov cx,primksz 是主分区? lea di,primk repne scasb jne dospri3 test byte ptr buf[1beh+si],80h ;取BootON jnz dospri2 cmp bp,4*16 jnz dospri3 dospri2:mov bp,si ;暂选首现主分区 jnz dospri5 dospri3:Add si,16 jmp dospri1 dospri4:cmp bp,4*16 je dospri6 dospri5:mov si,dx sub si,80h mov ax,bp div extblk mov fcbsz[si],al 标占分区表项号 mov al,kbd1 mov logidrv,al inc kbd1 Call Show dospri6:inc dl ;读下块硬盘 jmp dospri0 dospri7:ret dospri endp pri_non proc mov logidrv,32 mov cx,primksz lea di,primk repne scasb jne non ;不赋非DOS分区盘符 mov logidrv,94 ^符 mov al,kbd1 cmp al,'Z' ja non mov logidrv,al inc kbd1 non: Call Show ret pri_non endp dosext proc 查DOS扩展分区 dosext0:cmp dl,mod_p je dosext4 mov ax,201h mov cx,1 int 13h xor bp,bp dosext1:cmp bp,4*16 je dosext3 mov al,buf[1beh+bp+4] mov cx,extmksz 是扩展分区? lea di,extmk repne scasb jne dosext2 push bx push dx Call h_geo pop dx pop bx mov ax,word ptr buf[1beh+bp+8] ;Front low mov entrydi,ax 基址 mov lbal,ax mov ax,word ptr buf[1beh+bp+10] ;Front high mov entryes,ax mov lbah,ax xor bp,bp ;为show Call chain jmp dosext3 dosext2:Add bp,16 jmp dosext1 dosext3:inc dl jmp dosext0 dosext4:ret dosext endp h_geo proc mov drv_p,0 非扩展i13 mov ah,41h mov bx,55aah ;测BIOS支持扩展i13? int 13h jc h_geo1 cmp bx,0aa55h 再核 jne h_geo1 test cx,1 ;支持41~44,47~48第1子集? jz h_geo1 inc drv_p 支持 mov ah,48h 取尺寸 lea si,info_sz int 13h mov al,heads00 ;头数 mov media_h,al mov ah,s1track00 ;每道扇数 mov s1track,ah mul ah mov s1cyl,ax 每柱面扇数 mov ax,cylinders0 ;柱面数 mov media_c,ax ret h_geo1:mov ah,8 ;传统int 13取尺寸 int 13h jc h_geo2 inc dh mov al,dh mov media_h,al ;头数 mov s1track,cl and s1track,63 每道扇数
|