简单的引导加载程序无法在真机上读取 int 13h 的扇区

Simple bootloader fails reading sectors with int 13h on a real machine

我的简单引导加载程序代码有一个奇怪的问题。
它应该通过BIOS中断13h函数02h从磁盘读取一个扇区到文本模式的显存中(只是为了看看它是否有效)。它在模拟器(Bochs、QEmu)上工作得很好,但是当我尝试从连接到真实机器(Acer Extensa 5620Z)的 pendrive 启动它时,它只是清除屏幕并打印:

PCI System Error on Bus/Device/Function 0000h
PCI System Error on Bus/Device/Function 0200h

它似乎没有加载任何数据。调用该中断后没有设置进位标志,AH 中也没有错误代码,只有 1(应该是读取的扇区数)。

这是代码的相关部分:

          mov   bootdev,   %dl      # Device we're booting from.

          # ES=B800 (video memory segment in mode 03h)
          mov   [=11=]xB800,   %ax
          mov   %ax,       %es

          # Read one block.
          mov   [=11=]x0001,   %cx      # C:0, S;1
          mov   [=11=]x00,     %dh      # H:0
          xor   %bx,       %bx      # ES:BX = B800:0000 = output buffer.
          mov   [=11=]x0201,   %ax      # Function 02h: read sectors (just one).
          stc
          int   [=11=]x13               # Disk controller BIOS interrupt.
          jc    error               # On error, print an error message.

我们启动的设备编号来自 BIOS 本身(在 DL 中)并存储在 bootdev 中供以后使用。这个数字似乎没问题,我可以调用中断 13h 的函数 08h 从中获取正确的驱动器几何形状。只是当我尝试加载任何功能为 02h 的扇区时,出现此错误消息。

有什么想法是错误的吗?

"real" 机器与虚拟机相比有两点不同:

第一:由于机械延迟,软盘驱动器在真正读取数据之前可能会出现故障,真实的软盘驱动器有而模拟的没有延迟。因为您是从 USB 启动,所以这不是原因。

其次:内存组件不是模拟的而是真实的。您无法确定地址 B800:0 处的内存在真机上是否表现得像 "normal" RAM。 B800:0 不是 "regular" RAM,而是图形 RAM,其行为可能与常规 RAM 不同。尝试改为读取地址 9000:0,然后使用 "REP MOVSW".

将数据复制到 B800:0