BIOS.Режим чтения LBA не читает секторы - PullRequest
0 голосов
/ 23 ноября 2018

Я работаю над своим собственным загрузчиком и использую QEMU в качестве тестовой лаборатории для проверки / отладки.Прямо сейчас я хочу попрактиковаться с чтением секторов, используя расширения 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, а затем считывает 1 сектор, начиная с LBA = 0h, в память 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 голосов
/ 23 ноября 2018

В пакете доступа к диску (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
...