Reputation: 14659
I have a strange problem with my simple bootloader code.
It is supposed to read a sector from disk through BIOS interrupt 13h function 02h into the video memory of the text mode (just to see if it works). It works perfectly fine on emulators (Bochs, QEmu), but when I try to boot it from a pendrive attached to a real machine (Acer Extensa 5620Z), it just clears the screen and prints:
PCI System Error on Bus/Device/Function 0000h
PCI System Error on Bus/Device/Function 0200h
and it doesn't seem to load any data. There's no carry flag set after calling that interrupt and no error code in AH, just 1 (supposedly the number of sectors read).
Here's the relevant part of the code:
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.
The number of the device we're booting from comes from the BIOS itself (in DL
) and is stored in bootdev
for later use. This number seems to be OK, I can call function 08h of the interrupt 13h to get the correct drive geometry from it. It's just when I try to load any sectors with function 02h, this error message appears.
Any ideas what could be wrong?
Upvotes: 1
Views: 801
Reputation: 18493
There are two things that are different on a "real" machine compared to a virtual machine:
First: Floppy drives may fail some times until they really read data due to mechanical delays real floppy drives have while simulated ones do not have delays. Because you are booting from USB this cannot be the reason.
Second: The memory components are not emulated but real. You cannot be sure if the memory at address B800:0 behaves like "normal" RAM on a real machine. B800:0 is not "regular" RAM but graphics RAM which may behave different than regular one. Try to read to address 9000:0 instead and then copy the data to B800:0 using "REP MOVSW".
Upvotes: 1