关于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等代码。