为什么BIOS INT 13H使用AH=2时每次只能读取72个扇区?

7
我正在使用Bochs 2.4.5编写引导扇区代码。我使用INT 13H从软盘中读取扇区。但是我发现,如果要读取的扇区数>72,则INT13会失败。返回码为AH = 1。以下是代码,这里是INT13。返回码为AH = 1。
为什么INT 13H不能读取超过72个扇区?
   xorb %ah, %ah
   xorb %dl, %dl
   int $0x13      # reset the floppy

   movw $0x8000, %ax
   movw %ax,%es        
   movw $0, %bx  # ES:BX is the buffer  
   movb $0x02, %ah
   movb $73, %al # how many sectors to read. 72 is ok, but >=73 is wrong.
   movb $0, %ch
   movb $1, %cl
   movb $0, %dh
   movb $0, %dl

   int $0x13

感谢任何帮助。

更新

按照Matthew Slattery的指示,我找到了相应的代码。我在这里列出来,为像我一样困惑的其他人提供帮助。完整的代码可以在这里找到。

7220       if ((drive > 1) || (head > 1) || (sector == 0) ||
7221           (num_sectors == 0) || (num_sectors > 72)) {
7222         BX_INFO("int13_diskette: read/write/verify: parameter out of range\n");
7223         SET_AH(1);
7224         set_diskette_ret_status(1);
7225         SET_AL(0); // no sectors read
7226         SET_CF(); // error occurred
7227         return;
7228       }
3个回答

5

你正在使用Bochs,因此答案可以在Bochs BIOS源代码中找到:BIOS对扇区数进行了显式的范围检查,如果扇区数大于72(或等于0),则会被拒绝。


我并不是汇编语言的老手。你能指出范围检查在哪里吗? - smwikipedia
我的回答中的链接应该会带您到正确的位置,即C代码:bios/rombios.c的第7211行(截至Bochs v2.4.5),实际上是int13_diskette_function()内相关case语句的开头 - 参数验证(包括范围检查)是其中的第一个if (...),位于7220-7221行。 - Matthew Slattery
1
我想在这里发表评论/问题,你是否应该考虑每个磁道的扇区数?也就是说,在1.44mb软盘上调用BIOS中断0x13并请求超过18个扇区真的有效吗?如果您的引导加载程序正在从连续的簇中读取数据,那么它应该进行计算以根据需要推进任何磁道/柱面。 - chaz
1
这取决于BIOS和硬件。真正的软盘控制器应该至少允许一次从两个磁头中读取(多轨模式),而真正的BIOS 可能 支持此功能。Bochs BIOS接受高达72个扇区的请求,并向FDC发出单个命令;Bochs模拟的FDC 可以愉快地在多轨模式下前进到下一个柱面。因此,在Bochs中可以工作,但如果计划在真实系统上运行,则可能值得更加谨慎。 - Matthew Slattery

2
Matthew Slattery所指出的简单答案是,这仅是由Bochs执行的范围检查。这是基于一个2.88Mb软盘多轨软盘控制器读取,其将被限制为72个扇区。
快乐的答案是,由于向后兼容性,当前BIOS仅支持单面读取,对于1.44Mb软盘而言最多只支持18个扇区。这取决于起始扇区,因此实际上最大值可能达到轨道上剩余的总数。从USB闪存驱动器引导和运行是操作系统开发中取代过时软盘的简单选择。可以使用相同的BIOS磁盘/软盘功能,具体取决于引导驱动器标识符(dl寄存器)。

0
根据MS-DOS支持的标准软盘, 1.44 MB软盘每个磁道的扇区数为18。由于18 * 4 = 72,这可能是一个线索。BIOS可能不想一次读取太多的磁道。

谢谢你的提示。但是为什么要乘以4?我会继续寻找。 - smwikipedia
1
虽然这篇文章已经快4年了,但我想提出一点观察。我认为Bochs选择的72并不是随意的。72恰好是最大容量软盘(2.88MB软盘,每个磁道36个扇区,2个磁头)单个柱面上的扇区数。36*2=72。 - Michael Petch
继续阅读...此外,并非所有BIOS都支持跨越柱面边界的读取,因此您应该假定无法跨越它进行编程。因此,在出现的任何软盘格式中,根据我之前的评论所述,最大的有意义的值是72。 - Michael Petch

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接