Search code examples
assemblyx86nasmbootloaderbare-metal

Bootloader does not work on actual computer


I know this question has been asked before, but none of the other answers seem to have solved my problem. Maybe I missed something?

I know the .iso works because I ran it in QEMU and it worked successfully. So what am I doing wrong?

bits 16

xor ax, ax

start:
    cld               ; Set direction flag to forward

    ; Set up registers
    mov ax, 07c0h     ; Segment location which BIOS loads
    add ax, 288       ; (4096 + 512) / 16 bytes
    mov ss, ax        ; Sets stack segment register
    mov sp, 4096      ; Sets stack pointer register (offset of stack)

    mov ax, 07c0h
    mov ds, ax        ; Sets data segment to where we're loaded

    mov si, text      ; Puts string into source index
    call print_string ; Calls print string

    jmp $             ; Infinite loop to prevent shutdown

print_string:
    mov ah, 0eh       ; System call for printing
    xor bh, bh        ; Sets BH register to 0

.repeat:
    lodsb             ; Loads byte into AL
    cmp al, 0         ; Sees if AL is 0
    je .done          ; Jumps to done if AL is zero

    int 10h           ; Otherwise, print
    jmp .repeat       ; Repeat

.done:
    ret

text db 'Test', 0

times 510 - ($ - $$) db 0 ; Pads 510 - (current location - start location) zeros
dw 0xAA55                 ; Standard PC boot signature (takes up 2 bytes)

Edit: I've added the following to my code:

xor ax, ax
cld
xor bh, bh

For creating an iso, I run the following commands:

dd if=/dev/zero of=floppy.img bs=1024 count=1440
dd if=bootloader.bin of=floppy.img seek=0 count=1 conv=notrunc
mkdir iso
cp floppy.img iso/
mkisofs -o file.iso -b floppy.img iso

For burning the iso to my usb, I run the following commands:

umount /dev/sdX
dd if=/home/mint/Downloads/file.iso of=/dev/sdX bs=4M && sync

Solution

  • Your problem is that the "iso" you created is an optical disc image. It's bootable on a real computer only when its burned to an optical disc (eg. a CD-R). When you're using it with QEMU you're apparently using it as an emulated CD-ROM. When you copy it to your USB drive it's not in the correct format for booting on a USB drive.

    Fortunately the correct format for booting off an USB drive is simple: your bootloader just needs to be on the first sector of the drive, just like on floppy or a hard disk. So you can skip the creating an "iso" part, and just write the boot sector directly to the USB drive. For example:

    dd if=bootloader.bin of=/dev/sdX