关于bootsect.s保存每磁道扇区数的问题
81 ! Get disk drive parameters, specifically nr of sectors/track
! 取磁盘驱动器的参数,特别是每道的扇区数量。
! 取磁盘驱动器参数INT 0x13 调用格式和返回信息如下:
! ah = 0x08 dl = 驱动器号(如果是硬盘则要置位7 为1)。
! 返回信息:
! 如果出错则CF 置位,并且ah = 状态码。
! ah = 0, al = 0, bl = 驱动器类型(AT/PS2)
! ch = 最大磁道号的低8 位,cl = 每磁道最大扇区数(位0-5),最大磁道号高2 位(位6-7)
! dh = 最大磁头数, dl = 驱动器数量,
! es:di -.. 软驱磁盘参数表。
82
83 mov dl,#0x00
84 mov ax,#0x0800 ! AH=8 is get drive parameters
85 int 0x13
86 mov ch,#0x00
87 seg cs
88 mov sectors,cx ! 保存每磁道扇区数。
根据注释,cl的低6位保存的才是扇区数,86行只将CH置0,CL的高2位没有置0,88行sectors得到的值岂不是错的?
请斑竹指教,谢谢
flw 发表于 2004-10-19 12:17
关于bootsect.s保存每磁道扇区数的问题
这个我看的时候也注意到了,我的理解是这样的:
因为 cl 的高两位表示最大磁道号的高两位,
而光 ch 所能表示的磁道号就已经是 256 了,
而现有的硬盘的磁道数远远没有这么多,
所以这两位应该总是 0,大概是作者忽略了吧。
另外,你可以看看新的 linux 的内核,看这个地方是不是还是这样写的。
caolingzi 发表于 2004-10-19 12:18
关于bootsect.s保存每磁道扇区数的问题
[这个贴子最后由caolingzi在 2004/10/19 12:29pm 第 1 次编辑]
在
67 load_setup:
68 mov dx,#0x0000
69 mov cx,#0x0002 #第6,7位均为0。
在这期间程序执行,cl值并没有发生改变。
wangf501 发表于 2004-10-19 14:52
关于bootsect.s保存每磁道扇区数的问题
[这个贴子最后由wangf501在 2004/10/19 02:53pm 第 1 次编辑]
flw,你的想法和我想的差不多,但这种写法不够严谨.
MINIX的boothead.s中实现类似功能的代码是
3464 movb ah, #0x08 ! Code for drive parameters
3465 int 0x13 ! dl still contains drive
int 0x13, ah=0x08 returns the device geometry of the drive specified by dl. dl is 0x80 for the first drive, 0x81 for the second, 0x82 for the third and 0x83 for the fourth. The call returns the maximum sector number in bits 0-6 of cl and the maximum head number in dh. Adding to the confusion, the value that int 0x13, ah=0x08 returns for the maximum head number has a 0-origin. This means that if int 0x13, ah=0x08 returns a 15 for the maximum head number, there are actually 16 heads. This is why dh is incremented on line 3468.
3466 jc geoerr ! No such drive?
3467 andb cl, #0x3F ! cl = max sector number (1-origin)
3467行确实只取了CL的低6位,这样的代码才能称得上健壮.
caolingzi,你的说法恐怕有问题,85行再次调用INT 0X13后相关寄存器的值发生了变化.
caolingzi 发表于 2004-10-19 15:42
关于bootsect.s保存每磁道扇区数的问题
INT13,应该只改变ax,和dx吧.
flw 发表于 2004-10-19 16:32
关于bootsect.s保存每磁道扇区数的问题
[quote][b]下面引用由[u]caolingzi[/u]在 [i]2004/10/19 03:42pm[/i] 发表的内容:[/b]
INT13,应该只改变ax,和dx吧.
[/quote]
int 1308 会影响很多寄存器,可以说是影响寄存器较多的中断调用,
它有可能会影响 AX、BX、CX、DX、DI、ES 等寄存器。
完整用法如下:
[quote]INT 13h, 08h (8) Get Current Drive Parameters fixed
Reports disk drive parameters, such as the number of heads, tracks,
and sectors per track.
On entry: AH 08h
DL Drive number
Returns: CH Maximum value for cylinder (10-bit value;
upper 2 bits in CL)
CL Maximum value for sector
DH Maximum value for heads
For Fixed Disks:
AH Status of operation (See Service 01h)
DL Number of fixed disks
CF Set if error; otherwise cleared
For Diskettes:
AX 0
BL Bits 7 to 4 = 0
Bits 3 to 0 -- Valid drive type in CMOS
(See below)
BH 0
DL Number of diskettes
ES:DI Pointer to 11-byte Diskette Drive
Parameter Table.
--------------------------------------------------------------------------
Notes: This service is available for diskettes on PC
Convertibles, XT-286s, and ATs dated after 1/10/84.
All machines support the fixed disk mode of this
service.
Values in DL less than 80h specify diskettes; values
greater than 80h specify fixed disks. For example, 0
means the first diskette, while 80h means the first
fixed disk.
The cylinder number is a ten-bit quantity (0 through
1023). Its most significant two bits are in bits 7
and 6 of CL; the remaining eight bits are in CH. The
starting sector number fits in the low-order portion
(lower 6 bits) of CL.
If the drive is a fixed disk and there is an error,
the Carry Flag will be set. If the drive number is
invalid, AH will be equal to 7. And if no fixed disk
drive is present or the fixed disk drive adapter is
not installed, AH will be equal to 1.
If the drive is a diskette and there is an error,
then:
If the drive type is known but 1) the CMOS is invalid,
not present, 2) the battery is discharged, or 3) the
CMOS checksum is invalid, then all registers will
contain valid information, but BL will be 0.
If the drive type is not known or the requested drive is
not installed, then BX, CX, DH, ES, and DI will all be
0. DL will contain the number of diskette drives.
Valid Diskette Drive Types in CMOS
BL (bits 3-0) Meaning
00h Unknown drive type
01h 360K, 5.25 inch, 40 track
02h 1.2M, 5.25 inch, 80 track
03h 720K, 3.5 inch, 80 track
04h 1.44MB, 3.5 inch, 80 track
For the AT, XT-286, and PC Convertible, the BIOS
executes INT 15h, Service 90h (Device Busy), for the
diskette (Type = 01h) and the fixed disk (Type =
00h) prior to waiting for the interrupt. INT 15h,
Service 91h (Interrupt Complete), is executed upon
completion. Also diskette operations that require
the diskette motor to be on will call INT 15h,
Service 90 (Device Busy), with the type equal to
"Diskette Drive Motor Start" (Type = FDh). This
allows the system to perform another task while the
drive motor is waiting to get up to speed.
[/quote]
flw 发表于 2004-10-19 16:36
关于bootsect.s保存每磁道扇区数的问题
[quote][b]下面引用由[u]wangf501[/u]在 [i]2004/10/19 02:52pm[/i] 发表的内容:[/b]
3467行确实只取了CL的低6位,这样的代码才能称得上健壮.[/quote]
新的 linux 应该早就改进了吧?
没有看过,最近比较忙,都顾不上了。
另外,INT 13 AH=08本身也不太可靠,新版本中用了猜的办法:
157 #if 0
158
159 ! bde - the Phoenix BIOS manual says function 0x08 only works for fixed
160 ! disks. It doesn't work for one of my BIOS's (1987 Award). It was
161 ! fatal not to check the error code.
162
163 xor dl,dl
164 mov ah,#0x08 ! AH=8 is get drive parameters
165 int 0x13
166 xor ch,ch
167 #else
168
169 ! It seems that there is no BIOS call to get the number of sectors. Guess
170 ! 36 sectors if sector 36 can be read, 18 sectors if sector 18 can be read,
171 ! 15 if sector 15 can be read. Otherwise guess 9.
172
173 mov si,#disksizes ! table of sizes to try
174
175 probe_loop:
176 lodsb
177 cbw ! extend to word
178 mov sectors, ax
179 cmp si,#disksizes+4
180 jae got_sectors ! if all else fails, try 9
181 xchg ax, cx ! cx = track and sector
182 xor dx, dx ! drive 0, head 0
183 xor bl, bl
184 mov bh,setup_sects
185 inc bh
186 shl bh,#1 ! address after setup (es = cs)
187 mov ax,#0x0201 ! service 2, 1 sector
188 int 0x13
189 jc probe_loop ! try next value
190
191 #endif
我的个人理解是,内核的长度不会超过256磁道的。粗略估计一下,就是按软盘也就40个或80个磁道。硬盘磁道>1000的有很多。但是就按一磁道存储4k(当然元远大于4K),256个磁道也能存储4K*256字节了。内核的长度大家都知道地。
象这些代码如果赵博能在书中加以注释的话,肯定又是书的另个闪光点
mopyman 发表于 2005-7-5 23:26
关于bootsect.s保存每磁道扇区数的问题
因为这段代码是用于软盘引导的,而软盘的磁道是不会超过2 pow 8=256的,所以高2位一定是0了!
1.2.2 调用BIOS中断:ah=0x08,int 0x13得到磁盘驱动器参数。
其BIOS中断调用ah=0x08,int 0x13说明如下:
中断调用ah=0x08,int 0x13返回后,在以下寄存器返回以下信息:
DL:本机软盘驱动器的数目
DH:最大磁头号(或说磁面数目)。0表示有1个磁面,1表示有2个磁面
CH:存放10位磁道柱面数的低8位(高2位在CL的D7、D6中)。1表示有1个柱面,2表示有2个柱面,依次类推。
CL:0~5位存放每磁道的扇区数目。6和7位表示10位磁道柱面数的高2位。
AX=0
BH=0
BL表示驱动器类型:
1=360K 5.25
2=1.2M 5.25
3=720K 3.5
4=1.44M 3.5
ES:SI 指向软盘参数表
错误信息:
若产生错误,进位标志CF=1,AH存放错误信息码。
1.2.3 把以上得到的磁盘参数分别放到parameters处相应的位置,磁盘参数占11字节的空间。
1.2.4 根据上面得到的磁盘参数调用BIOS中断ah=0x02H,int 13H来读取第1扇区,且把它存放在地址0:0x1000处。
1.2.5 跳转到0:0x1000处执行装载kernel、mm、fs、net等代码。