Я написал загрузчик, но он всегда переходит к разделу ошибок, который я написал, и не загружает мой этап 2 - PullRequest
0 голосов
/ 25 ноября 2018

Я написал загрузчик, который должен загрузить мой KRNLDR.SYS в файл img в формате FAT12.Но это не работает

Команды, которые я использовал для его создания:

nasm -fbin -o boot.bin boot.asm
dd if=/dev/zero of=test.img bs=512 count=2880
sudo losetup /dev/loop0 test.img
sudo mkdosfs -F 12 /dev/loop0

Теперь моя система распознает и монтирует устройство, и я помещаю на него свой KRNLDR.SYS

Затем я выполнил:

sudo dd if=boot.bin of=/dev/loop0 bs=512 count=1 conv=notrunc
sudo umount /dev/loop0
sudo losetup -d /dev/loop0

Теперь файл выглядит как дискета FAT12 с загрузочным сектором и файлом KRNLDR.SYS

Теперь я выполняю его в QEMU:

qemu-system-i386 -device format=raw,file=test.img 

И вывод:

Operating System not found
Press any key to reboot

Это вывод, который мой загрузчик выводит на экран, если мой загрузчик не может найти файл KRNLDR.SYS

Мой код:

org 0x0
bits 16

    jmp     word loader

bsOEMName:                  db "TestOS  "
bpbBytesPerSector:          dw 512
bpbSectorsPerCluster:       db 1
bpbReservedSectors:         dw 1
bpbNumberOfFATs:            db 2
bpbNumberOfRootEntries:     dw 224
bpbTotalSectors:            dw 2880
bpbMedia:                   db 0xf0
bpbSectorsPerFAT:           dw 9
bpbSectorsPerTrack:         dw 18
bpbNumberOfHeads:           dw 2
bpbHiddenSectors:           dd 0
bpbTotalSectorsBig:         dd 0
bsDriveNumber:              db 0
bsReserved:                 db 0
bsExtendedBootSignature:    db 0x29
bsVolumeID:                 dd 0x12345678
bsVolumeLabel:              db "TestOS     "
bsFileSystem:               db "FAT12   "

;-------------------------------------------------------------------------------
; SI = Zero terminated string to print
;-------------------------------------------------------------------------------

printMsg:
    push    ax

.printStart:
    lodsb
    or      al, al
    jz      .printEnd

    mov     ah, 0x0e
    int     0x10
    jmp     .printStart

.printEnd:
    pop     ax

    ret

;-------------------------------------------------------------------------------
; AX = Starting sector
; CX = Number of sectors to read
; ES:BX = Buffer
;-------------------------------------------------------------------------------

readSectors:
    mov     di, 0x0005

.readLoop:
    push    ax
    push    bx
    push    cx

    call    lbaToChs

    mov     ah, 0x02
    mov     al, 0x01
    mov     ch, byte [track]
    mov     cl, byte [sector]
    mov     dh, byte [head]
    mov     dl, byte [bsDriveNumber]
    int     0x13
    jnc     .success

    dec     di
    pop     cx
    pop     bx
    pop     ax
    jnz     .readLoop

.success:
    pop     cx
    pop     bx
    pop     ax

    inc     ax
    add     bx, word [bpbBytesPerSector]
    loop    readSectors

    ret

track:      db      0
head:       db      0
sector:     db      0

;-------------------------------------------------------------------------------
; AX = Logical sector
;-------------------------------------------------------------------------------

lbaToChs:
    xor     dx, dx
    div     word [bpbSectorsPerTrack]
    inc     dl
    mov     byte [sector], dl

    xor     dx, dx
    div     word [bpbNumberOfHeads]
    mov     byte [head], dl
    mov     byte [track], al

    ret

;-------------------------------------------------------------------------------
; AX = Cluster number
;-------------------------------------------------------------------------------

clusterToLba:
    sub     ax, 0x0002
    xor     cx, cx
    mov     cl, byte [bpbSectorsPerCluster]
    mul     cx

    ret

;-------------------------------------------------------------------------------

loader:
    cli

    mov     ax, 0x07c0
    mov     es, ax
    mov     gs, ax
    mov     fs, ax
    mov     ds, ax

    mov     ax, 0x0000
    mov     ss, ax
    mov     sp, 0xffff

    sti

    mov     byte [bsDriveNumber], dl

    xor     dx, dx
    xor     cx, cx
    mov     ax, 0x0020
    mul     word [bpbNumberOfRootEntries]
    div     word [bpbBytesPerSector]
    xchg    cx, ax ; Number of sectors of the root directory

    mov     al, byte [bpbNumberOfFATs]
    mul     word [bpbSectorsPerFAT]
    add     ax, word [bpbReservedSectors] ; Starting sector of the root directory

    mov     bx, 0x0200
    call    readSectors

    mov     cx, word [bpbNumberOfRootEntries]
    mov     di, 0x0200

searchRoot:
    push    cx
    mov     cx, 0x000b
    mov     si, stage2

    push    di
    rep cmpsb
    pop     di

    je      loadFat
    pop     cx
    add     di, 0x0020
    loop    searchRoot

    jmp     failure

loadFat:
    mov     dx, [di + 26] ; Starting address of entry
    xor     ax, ax
    mov     al, byte [bpbNumberOfFATs]
    mul     word [bpbSectorsPerFAT] ; Number of sectors used by the FATs

    mov     word [cluster], dx
    mov     cx, ax
    mov     ax, word [bpbReservedSectors]

    mov     bx, 0x0200
    call    readSectors

    mov     ax, 0x0050
    mov     es, ax
    mov     bx, 0x0000
    push    bx

loadFile:
    mov     ax, word [cluster]
    pop     bx
    call    clusterToLba
    xor     cx, cx
    mov     cl, byte [bpbSectorsPerCluster]
    call    readSectors
    push    bx

    mov     ax, word [cluster]

    mov     cx, ax
    mov     dx, ax
    shr     dx, 1
    add     cx, dx

    mov     bx, 0x0200
    add     bx, cx
    mov     dx, [bx]

    test    ax, 1
    jnz     oddCluster

evenCluster:
    and     dx, 0b0000111111111111
    jmp     next

oddCluster:
    shr     dx, 4

next:
    mov     word [cluster], dx
    cmp     dx, 0x0ff0
    jb      loadFile

    jmp     0x0050:0 ; Far jmp to KRNLDR.SYS

failure:
    mov     si, fail
    call    printMsg

    mov     si, anykey
    call    printMsg

    mov     ah, 0x00
    int     0x16 ; Await key press

    jmp     0xffff:0 ; Reboot with far jmp to BIOS

stage2:         db          "KRNLDR  SYS"
fail:           db          "Operating system not found", 0xd, 0xa, 0x0
anykey:         db          "Press any key to reboot", 0xd, 0xa, 0x0

cluster:        dw          0

times 510 - ($ - $$) db 0
dw 0xaa55

Что я могу сделать?Спасибо за любую помощь

1 Ответ

0 голосов
/ 21 июля 2019
loadFat:
    mov     dx, [di + 26] ; Starting address of entry
    xor     ax, ax
    mov     al, byte [bpbNumberOfFATs]
    mul     word [bpbSectorsPerFAT] ; Number of sectors used by the FATs

    mov     word [cluster], dx

Одна проблема здесь заключается в том, что mul с операндом слова умножает это слово на ax и оставляет результат в паре регистров dx:ax.Таким образом, вы перезаписываете dx нулем, прежде чем использовать его для инициализации переменной с именем cluster.При преобразовании этого входного индекса FAT в номер сектора вычитание 2 из нуля приводит к очень большому номеру сектора.

, что подводит нас ко второй проблеме, которую я заметил.Обычно ноль в [кластере] должен иметь 2 вычтенных из него, результат которого умножается на 1 (количество секторов на кластер), а затем добавляется «первый сектор данных», что снова приводит к очень низкому числу, котороеприведет к сбою, но, вероятно, несколько отличаются.Однако ваш clusterToLba фактически не преобразуется в начальный сектор LBA для данных этого кластера, поскольку он не добавляет «первый сектор данных» (т. Е. Номер LBA первого сектора первого кластера).Это должно быть вычислено вашим загрузчиком.Это начальный сектор корневого каталога плюс количество секторов корневого каталога.

...