I have been attempting to test a simple bootloader on my computer (i.e. physical machine) for a while, and I've run into some very odd behavior.
My bootloader is in a file named "boot.asm" and contains the following code:
[ORG 0x7c00]
start:
mov ax, cs
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x9000
mov si, mesg1
call print
mov ax, 0x0201 ;ah=0x02, al=0x01
mov bx, 0x5000 ;address = 0x5000 (I have also attempted this at 0x8000)
mov cx, 0x0002 ;ch=0x00, cl=0x02
mov dh, 0x0
int 0x13
mov si, mesg2
call print
jmp $
print:
pusha
mov ah, 0xe
xor bl, bl
.loop:
lodsb
test al, al
jz .end
int 0x10
jmp .loop
.end:
popa
ret
mesg1 db "Msg1", 0x0
mesg2 db "Tst1", 0x0
times 510 - ($ - $$) db 0x0
db 0x55, 0xaa
I compile it with a makefile that contains the following commands (kernel.asm contains nothing but junk and was only added for earlier testing):
nasm -f bin -o bin/boot.bin src/boot.asm
nasm -f bin -o bin/kernel.bin src/kernel.asm
cat bin/boot.bin bin/kernel.bin > boot.img
When I boot "boot.img" as a floppy in Virtualbox, I get the expected output on screen:
Msg1Tst1
The problem occurs when I attempt to run this on my physical computer. I copy the boot image to my flash drive with the following command:
sudo dd if=boot.img of=/dev/sdb
I then reboot my computer, and I get the most bizarre output:
Msg1Msg1
I can't figure out what's going on no matter how hard I try. After a little tinkering, I discovered that if I move the code,
mov si, mesg2
call print
before the read operation, it will give the expected output. Can somebody explain to me what I'm doing wrong? I've been at this for a day, and I can't figure out the problem.