Reputation: 23
I'm rolling my own simple, two-stage boot loader to load into a kernel I wrote recently. So far it's been a fantastic experience, and I've learned a lot polishing off what I believe to be a mostly functional first stage. But early in the program, interrupt 0x13 is repeatedly failing while trying to load in the root directory of my FAT12 filesystem.
With a handful of print calls, I've managed to narrow the problem down to figure out errors occur within my sector-read subroutine, which I'll include below. I've done lots of digging to try and be certain I'm setting up my segments correctly in the beginning of the program, along with all the parameters and functions preceding the actual read.
To clarify, this issue differs from other, similar questions in that much of the time, the INT13H read succeeds (i.e. the carry bit is set to 0) and then problems occur further down the line. In my situation, INT13 sets up the carry bit no matter what.
I'm emulating within QEMU, and have been using GDB to help in the debugging process.
My main program begins with org 0x0, and I set up proper segment location further on (saw this being done in a few places online with no issue, figured it looked cleaner)
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
Further on, I set up parameters for the function call:
; 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
Once called (immediately after parameter setup), the function is as follows. I'll include the entire body: I'm finding this difficult to debug, and suspect it might be a pretty small problem.
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
I'm compiling with NASM into binary format, and then flashing it to a floppy with a FAT12 filesystem via dd -- booting from it via QEMU. Using a virtual disk or just the binary with -fda produces the same problem.
sudo dd if=bootfirst.bin bs=512 of=/dev/disk2
sudo qemu-system-x86_64 -device floppy /dev/disk2
I'd appreciate any insight into seeing how this might be resolved, and am open to larger changes as needed. Thank you!
Upvotes: 1
Views: 74