Assembly 简单引导加载程序无法在实际机器上读取int为13h的扇区
我的简单引导加载程序代码有一个奇怪的问题。Assembly 简单引导加载程序无法在实际机器上读取int为13h的扇区,assembly,interrupt,bootloader,bios,usb-drive,Assembly,Interrupt,Bootloader,Bios,Usb Drive,我的简单引导加载程序代码有一个奇怪的问题。 它应该通过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
它应该通过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 $0xB800, %ax
mov %ax, %es
# Read one block.
mov $0x0001, %cx # C:0, S;1
mov $0x00, %dh # H:0
xor %bx, %bx # ES:BX = B800:0000 = output buffer.
mov $0x0201, %ax # Function 02h: read sectors (just one).
stc
int $0x13 # Disk controller BIOS interrupt.
jc error # On error, print an error message.
我们从中引导的设备的编号来自BIOS本身(在DL
中),并存储在bootdev
中,以供以后使用。这个数字似乎还可以,我可以调用中断13h的08h函数,从中获得正确的驱动器几何图形。就在我尝试使用函数02h加载任何扇区时,出现了此错误消息
有什么想法吗?与虚拟机相比,在“真实”机器上有两件事是不同的: 第一:软盘驱动器可能会出现故障,直到它们真正读取数据为止,这是由于真正的软盘驱动器有机械延迟,而模拟的软盘驱动器没有延迟。因为您是从USB启动的,所以这不是原因
第二:内存组件不是仿真的,而是真实的。您无法确定地址B800:0处的内存是否与实际机器上的“正常”RAM行为相同。B800:0不是“常规”RAM,而是图形RAM,其行为可能不同于常规RAM。尝试读取地址9000:0,然后使用“REP MOVSW”将数据复制到B800:0。谢谢您的建议,事实证明您是对的。当我将数据读入9000:0000,然后移到B800:0000时,它可以正常工作。不过,对我来说有点奇怪,我可以用
rep movsw
很好地读/写内存,BIOS也可以通过int 10h函数09h/0Ah/0Ch来读/写内存,但是当数据从磁盘缓冲区移动到视频缓冲区时,它无法做到。哇,很好的调用-这是出乎意料的。直接从软盘加载扇区使用DMA(8237 DMA控制器)。该内存区域不支持DMA AFAIK,因为它没有映射为普通RAM。