BIOS。 LBA模式读取不读取扇区

BIOS. LBA mode reading doesn't read sectors

我正在开发我自己的引导加载程序,我正在使用 QEMU 作为 check/debug 它的测试实验室。现在我想练习使用 BIOS 扩展读取扇区。根据文档,QEMU 使用 SeaBIOS,它应该支持 int 13h AH=42h。 我有这个代码

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

它使用AH=41h 函数检查是否支持扩展,然后读取从LBA=0h 开始的1 个扇区到内存0000:7E00。 我正在使用 gdb 连接到 qemu 机器来检查寄存器和内存。所以我看到的是

这就是我创建磁盘映像的方式

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 

这就是我 运行 qemu

的方式
qemu-system-x86_64 -s -S -hda ./floppy/floppy.img

能否请您帮助理解我做错了什么。 谢谢!

在磁盘访问数据包 (DAP) 中,segment:offset 对以先偏移后跟段的方式存储。这是因为 x86 是一个小端处理器,并且该对以相反的顺序存储。您的 DAP 应更改为:

dap:
packetSize: db 0x10
reserved:   db 0x0
sectorsNumber:  dw 0x1
buf_off:    dw 0x7E00              ; Place offset before segment
buf_seg:    dw 0x0000
lba:        dd 0x0
            dd 0x0