I am writing a bootloader in assembly and it seems to work fine on qemu, bochs and virtualbox. However, it is not loading the kernel on real hardware (it seems).
The bootloader starts off by writing a character to the video memory (for debugging), it then reads sector 2 off the drive and far jumps to the kernel. The kernel is then writing some characters to video memory.
On a real machine, I see the character from the bootloader on the screen, and there it hangs (blinking caret).
I have tried to set DS, ES, SI to zero, and I am also setting up a stack segment.
I am reading sector 2 off of the drive using bios int 13 function 2. I kind of suspect that it has something to do with the drive number. I have both tried to use the drive number passed to the bootloader on startup (in dl), and setting it manually to 0x0, 0x80 and 0x81.
One strange thing I noticed is that the labels I use to near jump, magically gets the correct address. Using objdump I see for example: jmp 0x2, while using gdb and qemu, it says: jmp 0x7c02. CS and all the other segment registers are zero. Whether I use -Ttext 0x0 or -Ttext 0x7c00 in the linking, the bootloader works fine on all the emulators. objdump says jmp 0x7c02 when I link with -Ttext 0x7c00.
EDIT, the bootloader looks like this:
.code16
.text
movw $0xb800, %ax
movw %ax, %ds
movw $0x0741, (0x0)
xorw %ax, %ax
movw %ax, %ds
movw %ax, %si
movw %ax, %es
movw $0x8000, %ax
movw %ax, %ss
movw $0, %sp
movb $2, %ah
movb $1, %al
movw $0x02, %cx
movb $0x00, %dh
movw $0x5000, %bx
movw %bx, %es
movw $0x0, %bx
int $0x13
ljmpw $0x5000, $0x0000
Edit, Second stage:
.code16
.text
movw $0xb800, %ax
movw %ax, %ds
movw $0x0742, (0x2)
forever:
jmp forever
If your hardware is using floppy disk emulation for the USB drive it may be possible that without a proper BIOS Parameter Block (BPB) in your MBR that it is failing to boot properly. Many BIOSes will attempt to detect a BPB at the start of the bootloader and may even update the values with proper drive geometry after the bootloader is loaded into memory. It is possible your bootloader was not being detected as a proper bootable drive or it was but the BIOS overwrote some of your code with drive geometry information before executing it.
The following adds a BPB that happens to look like a 2.88MB floppy.
.global _start
.code16
.text
_start:
jmp main
.space 3 - (.-_start)
/* Configuration for a 2.88MB floppy using FAT 12 */
OEMname: .ascii "MYBOOT "
bytesPerSector: .word 512
sectPerCluster: .byte 1
reservedSectors: .word 1
numFAT: .byte 2
numRootDirEntries: .word 240
numSectors: .word 5760
mediaType: .byte 0xf0
numFATsectors: .word 9
sectorsPerTrack: .word 36
numHeads: .word 2
numHiddenSectors: .long 0
numSectorsHuge: .long 0
driveNum: .byte 0
reserved: .byte 0x00
signature: .byte 0x29
volumeID: .long 0x54428E71
volumeLabel: .ascii "NO NAME "
fileSysType: .ascii "FAT12 "
main:
movw $0xb800, %ax
movw %ax, %ds
movw $0x0741, (0x0)
xorw %ax, %ax
movw %ax, %ds
movw %ax, %si
movw %ax, %es
movw $0x8000, %ax
movw %ax, %ss
movw $0, %sp
movb $2, %ah
movb $1, %al
movw $0x02, %cx
movb $0x00, %dh
movw $0x5000, %bx
movw %bx, %es
movw $0x0, %bx
int $0x13
ljmpw $0x5000, $0x0000
.space 510-(.-_start)
.word 0xaa55
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With