jaytlang
jaytlang

Reputation: 23

Repeated errors using interrupt 0x13 to read FAT12 root directory into memory

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

Answers (0)

Related Questions