『楼 主』:
关于获取磁盘参数c/h/s的探讨
系统启动时,要查找IO.SYS、NTLDR、GRLDR等,若系统不支持扩展读,需获取磁盘磁头数及每磁道扇区数。常用方法有四种。
1. 使用int13/ah=08获取。
CL(位7-6)+CH(位7-0)=柱面数,DH=磁头数,CL(位5-0)=每磁道扇区数。
注意:柱面数、磁头数从0开始,扇区数从1开始。
对于BIOS识别为软盘的u盘或img磁盘映像,BL=10,但有的BIOS存在bug,会给出错误参数。
由于柱面数最大为3FF,磁盘字节总数最大为8Gb,超过则不能表示。
2. 使用int13/ah=48获取。
DS:SI的偏移04=柱面数,偏移08=磁头数,偏移0C=每磁道扇区数,偏移10=磁盘总扇区数。
注意:柱面数、磁头数、扇区数从1开始。
应测试偏移02的标记(位7-0),若位1等于0,则不支持c/h/s参数获取,给出的c/h/s参数可能不正确,但磁盘总扇区数还是正确的。
3. 使用引导扇区DBR的BPB参数表获取。
对于FAT12,偏移1A=磁头数,偏移18=每磁道扇区数,偏移13=该分区总扇区数。
对于FAT16,偏移1A=磁头数,偏移18=每磁道扇区数,偏移20=该分区总扇区数。
对于FAT32、EXT2、EXT3,偏移1A=磁头数,偏移18=每磁道扇区数,偏移20=该分区总扇区数。
对于NTFS,偏移1A=磁头数,偏移18=每磁道扇区数,偏移28=该分区总扇区数。
注意:柱面数、磁头数、扇区数从1开始。
4. 使用主引导记录MBR获取。
偏移1C3=磁头数,偏移1C4(位5-0)=每磁道扇区数,偏移1CA=分区总扇区数。
注意:磁头数从0开始,扇区数从1开始。
本人认为第3、4种方法最方便可靠。因为查找IO.SYS、NTLDR、GRLDR等时,除了获取h/s参数,还需要获取BPB参数表的其他参数,如每簇扇区数、保留扇区数、隐含扇区数、$MFT(主文件表)的逻辑簇号、节点大小等等。既然要用到MBR及BPB,何不一并获取,而要舍近求远,舍简求繁?或许有人曰h/s参数可能被病毒破坏,那MBR及BPB的其他参数不也会被破坏?
5 对于c/h/s参数的探测,grldrstart.S采用逐次测试法,探测磁头数从1探测到FF,最少1次,最多255次,平均128次。若采用对折逼近法,只需8或9次。
程序代码如下:
testing: pusha
push ds
push es
mov bx,5000h
mov es,bx
mov ds,bx
xor bp,bp
;初始化测试扇区参数
mov cx,20h ;初始测试值
mov bh,40h ;测试上限+1
xor bl,bl ;测试下限
read: pusha
xor bx,bx ;读到5000:0000
cmp bp,0 ;测试扇区数?
jne read_head ;不是
;测试每磁道扇区数
mov ax,0201h
xor ch,ch
xor dh,dh
int 13h
jmp read_end ;成功
read_head: ;测试最大磁头号
mov dh,cl
mov ax,0201h
mov cx,1
int 13h
read_end: popa
jb failure
;测试成功处理
mov ch,cl ;保存成功值
mov bl,cl ;修正下限
mov cl,bh
;计算新测试值
new: sub cl,bl
shr cl,1
add cl,bl
cmp cl,0
je err
cmp ch,cl ;测试完毕退出
je done
jmp read
;测试失败处理
failure: mov bh,cl ;修正上限
jmp new
done: test bp,1 ;测试完最大磁头号?
je done_sector ;不是
inc ch
mov cs:[head],ch ;保存测试成功的磁头数
jmp test_end
done_sector:
mov cs:[sector],ch ;保存测试成功的每磁头扇区数
;测试最大磁头号
or bp,1 ;测试最大磁头号标记
;专为虚拟机vpc的bug设置
;读1扇区 0-0-1 -> 5000:0000
xor bx,bx
mov ax,0201h
mov cx,1
xor dh,dh
int 13h
;读1扇区 0-2-1 -> 5000:0200
mov ax,0201h
mov dh,2
mov bx,0200h
int 13h
;比较 5000:0000<>5000:0200
xor si,si
mov di,0200h
mov cx,80h
repz cmpsd
jne general ;不相等正常测试
mov byte ptr cs:[head],2
jmp test_end
general: ;正常测试最大磁头号
;初始化测试磁头参数
mov cx,7fh ;初始测试值
mov bh,0ffh ;测试上限+1
xor bl,bl ;测试下限
jmp read
err: stc
test_end:
pop es
pop ds
popa
ret 上传一个探测程序,请把rar改为com。
附件
1: test.rar (2009-1-9 17:05, 706 bytes,下载次数: 23)
|