Я запускаю свой собственный простой двухэтапный загрузчик для загрузки в ядро, которое я недавно написал. До сих пор это был фантастический опыт, и я многому научился оттачивать то, что я считаю наиболее функциональным первым этапом. Но в начале программы прерывание 0x13 неоднократно завершалось ошибкой при попытке загрузки в корневой каталог моей файловой системы FAT12.
С помощью нескольких вызовов печати мне удалось сузить проблему, чтобы выяснить, какие ошибки возникают в моей подпрограмме чтения секторов, которую я включу ниже. Я сделал много копаний, чтобы убедиться, что я правильно настраиваю свои сегменты в начале программы, а также все параметры и функции, предшествующие фактическому чтению.
Чтобы уточнить, эта проблема отличается от других подобных вопросов тем, что чтение INT13H успешно выполняется (т. Е. Бит переноса установлен на 0), а затем возникают проблемы в дальнейшем. В моей ситуации INT13 устанавливает бит переноса, несмотря ни на что.
Я эмулирую в QEMU и использую GDB для помощи в процессе отладки.
Моя основная программа начинается с org 0x0, и я в дальнейшем настраивал правильное расположение сегментов (видел, что это делается в нескольких местах онлайн без проблем, подумал, что это выглядит чище)
cli
mov ax, 0x07C0
mov ds, ax
mov es, ax ; ES gets set here
mov fs, ax
mov gs, ax
; Create the stack
mov ax, 0x8000
mov ss, ax
xor ax, ax
mov sp, ax
sti
Далее я настраиваю параметры для вызова функции:
; CX = size of the root directory in sectors
xor cx, cx
xor dx, dx
mov ax, 0x0020
mul word [bpbNumRootEntries]
div word [bpbBytesPerSector]
xchg ax, cx
; AX = where the root directory begins. BX = offset for ES:BX
mov al, byte [bpbNumberOfFATs]
mul word [bpbSectorsPerFAT]
add ax, word [bpbNumReservedSectors]
mov bx, 0x0200 ; Root dir. goes directly below code
После вызова (сразу после настройки параметров) функция работает следующим образом. Я включу все тело: мне трудно это отладить, и я подозреваю, что это может быть довольно маленькая проблема.
ReadSectors:
.begin
mov di, 0x000A
.loop
push ax
push bx
push cx
call LBACHS ; Converts LBA -> CHS
mov ah, 0x02
mov al, 0x01
mov ch, byte [absoluteTrack]
mov cl, byte [absoluteSector]
mov dh, byte [absoluteHead]
mov dl, byte [bpbDriveNumber]
int 0x13
jnc .finish
mov si, progmsg ; Keeps printing -> INT13H failing
call Print
xor ax, ax
int 0x13
dec di
pop cx
pop bx
pop ax
jnz .loop
jmp Failure
.finish
pop cx pop bx
pop ax
add bx, word [bpbBytesPerSector]
inc ax
loop .begin
ret
Я компилирую с NASM в двоичный формат, а затем перепрошиваю его на дискету с файловой системой FAT12 через dd - загружаясь с нее через QEMU. Использование виртуального диска или только двоичного файла с параметром -fda приводит к той же проблеме.
sudo dd if=bootfirst.bin bs=512 of=/dev/disk2
sudo qemu-system-x86_64 -device floppy /dev/disk2
Буду признателен за понимание того, как это можно решить, и я открыт для более крупных изменений по мере необходимости. Спасибо!