I'm working on my own bootloader and I'm using QEMU as a test lab to check/debug it. Right now I want to practice with reading of sectors using BIOS extensions. According to the docs QEMU uses SeaBIOS which should support int 13h AH=42h. I have this code
bits 16 ; we are in 16 bit real mode
org 0 ; we will set regisers later
start: jmp main ; jump to start of bootloader
Print:
lodsb ; load next byte from string from SI to AL
or al, al ; Does AL=0?
jz PrintDone ; Yep, null terminator found-bail out
mov ah, 0eh ; Nope-Print the character
int 10h
jmp Print ; Repeat until null terminator found
PrintDone:
ret ; we are done, so return
ReadSectors:
mov ah,0x42
mov dl,0x80
mov si,dap
int 0x13
jc .error
jmp .exit
.error:
mov si,msgFailure
call Print
cli
hlt
.exit:
ret
main:
;----------------------------------------------------
; code located at 0000:7C00, adjust segment registers
;----------------------------------------------------
cli ; disable interrupts
mov ax, 0x07C0 ; setup registers to point to our segment
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
;----------------------------------------------------
; create stack
;----------------------------------------------------
mov ax, 0x0000 ; set the stack
mov ss, ax
mov sp, 0xFFFF
sti ; restore interrupts
xor ax,ax
mov ah,0x41
xor dx,dx
mov dl,0x80
mov bx,0xAA55
int 0x13
;----------------------------------------------------
; Display loading message
;----------------------------------------------------
mov si, msgLoading
call Print
call ReadSectors
mov si,0x200
call Print
cli
hlt
dap:
packetSize: db 0x10
reserved: db 0x0
sectorsNumber: dw 0x1
buf_seg: dw 0x0000
buf_off: dw 0x7E00
lba: dd 0x0
dd 0x0
msgLoading db 0x0D, 0x0A, "Loading Boot Image ", 0x0D, 0x0A, 0x00
msgCRLF db 0x0D, 0x0A, 0x00
msgProgress db ".", 0x00
msgFailure db 0x0D, 0x0A, "ERROR : Press Any Key to Reboot", 0x0A, 0x00
TIMES 510-($-$$) DB 0
DW 0xAA55
It checks if the extensions are supported using AH=41h function and then reads 1 sector starting from LBA=0h to memory 0000:7E00. I'm using gdb to connect to qemu machine to check register and memory. So what I see is that
- int 13h AH=42 returns CF=0, so there is no error
- int 13h AH=41h returns CF=0,CX=7, so it means that BIOS supports extensions. But then I check memory at address 7E00 and I see only zeros, but I expect to see the code of bootloader as it is stored in the LBA=0h sector.
This is how I create disk image
nasm bootloader.asm -o ./bin/bootloader.bin
dd if=/dev/zero of=./floppy/floppy.img bs=1024 count=1440
dd if=./bin/bootloader.bin of=./floppy/floppy.img conv=notrunc
And this is how I run qemu
qemu-system-x86_64 -s -S -hda ./floppy/floppy.img
Can you please help with understanding what I'm doing wrong. Thanks!
buf_seg: dw 0x0000buf_off: dw 0x7E00should bebuf_off: dw 0x7E00buf_seg: dw 0x0000. The reason for this is because x86 is a little endian processor so segment:offset is stored as offset first and segment second. - Michael Petchorgdirective seems correct with respect to the segment selector OP chose. - fuzorg 0where he has it is correct, and he is also correct to load the segment registers with 0x07c0. That is because a segment:offset pair of 0x07c0:0x0000 is physical address 0x07c0<<4+0x000=0x07c00. Altrnatively he could have usedorg 0x7c00and set the segments to 0x0000 since 0x0000<<4+0x7c00 also equals = 0x07c00. Both represent the same physical memory address. - Michael Petchotgdoesn't matter. No matter where you place it, it acts as if was at the very beginning. - Michael Petch