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

时间:2018-11-23 00:27:45

标签: assembly x86 boot bios osdev

我正在使用自己的引导程序,正在使用QEMU作为测试实验室来对其进行检查/调试。现在,我想练习使用BIOS扩展读取扇区。根据文档,QEMU使用应支持int 13h AH = 42h的SeaBIOS。 我有此代码

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机器以检查寄存器和内存。所以我看到的是

  • int 13h AH = 42返回CF = 0,所以没有错误
  • int 13h AH = 41h返回CF = 0,CX = 7,因此表示BIOS支持扩展。 但是,然后我检查了地址7E00处的内存,并且只看到零,但是我希望看到引导加载程序的代码,因为它存储在LBA = 0h扇区中。

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

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

能帮我了解我在做什么错吗? 谢谢!

1 个答案:

答案 0 :(得分:3)

在磁盘访问数据包(DAP)中,存储段:偏移对,首先存储偏移,然后是段。这是因为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