fat32 bootloader: implement directory recursing and kernel load

this is actually working now.
This commit is contained in:
Nero 2020-03-30 18:50:17 +00:00
parent bbe006c9bc
commit 0b2a7e7b64

View File

@ -50,13 +50,15 @@ mloop: lodsb
mend: push si mend: push si
ret ret
dskerr: call msg
db "DISK", 0
err: call msg err: call msg
db "ERR", 0x0A, 0x0D, 0 db "ERR", 0x0A, 0x0D, 0
hlt: hlt hlt: hlt
jmp hlt jmp hlt
; offsets relative to FS ; offsets relative to FS
offd: ; add offset of cluster data area to DX:AX readd: ; add offset of cluster data area to DX:AX
push cx push cx
mov di, [rde] mov di, [rde]
mov cl, 4 mov cl, 4
@ -64,7 +66,7 @@ offd: ; add offset of cluster data area to DX:AX
add ax, di add ax, di
adc dx, 0 adc dx, 0
pop cx pop cx
offr: ; add offset to rootdir to DX:AX (FAT12/FAT16 only) readr: ; add offset to rootdir to DX:AX (FAT12/FAT16 only)
push cx push cx
xor ch, ch xor ch, ch
mov cl, byte [fn] mov cl, byte [fn]
@ -72,17 +74,14 @@ fatlp: add ax, [sf]
adc dx, [sf+2] adc dx, [sf+2]
loop fatlp loop fatlp
pop cx pop cx
offf: ; add offset to FAT table to DX:AX readf: ; add offset to FAT table to DX:AX
add ax, word [rsc] add ax, word [rsc]
adc dx, 0 adc dx, 0
ret
readp: ; read sector DX:AX from partition readp: ; read sector DX:AX from partition
add ax, word [po] add ax, word [po]
adc dx, word [po+2] adc dx, word [po+2]
jc err jc err
read_: ; read sector DX:AX from disk
readd: ; read sector DX:AX from disk
; qword sector number DX:AX ; qword sector number DX:AX
push cs push cs
push cs push cs
@ -105,16 +104,15 @@ readd: ; read sector DX:AX from disk
mov dl, 0x80 mov dl, 0x80
stc stc
int 0x13 int 0x13
jc err jc dskerr
add sp, bp add sp, bp
ret ret
next: ; Advances [clus] to next FAT entry next: ; Advances DX:AX to next FAT entry
; get current cluster number push ax
mov ax, [clus] push bx
mov dx, [clus+2]
; shift 2 left for dword-sized FAT entries ; shift 2 left for dword-sized FAT entries
; shift 9 right for sector size ; shift 9 right for sector size
@ -124,31 +122,30 @@ shftl: clc
rcr ax, 1 rcr ax, 1
loop shftl loop shftl
call offf
mov bx, 0xA0 mov bx, 0xA0
mov cx, 1 mov cx, 1
call readp call readf
; get lower part of cluster number pop bx
mov si, [clus]
; get lower part of cluster number
pop si
; multiply with 4 ; multiply with 4
sal si, 1 sal si, 1
sal si, 1 sal si, 1
; make sure its within sector range ; make sure its within sector range
and si, 0x1FF and si, 0x1FF
add si, buf add si, buf
mov di, clus ; load dword from FAT
; copy dword from FAT to [clus] lodsw
movsw mov dx, [si]
movsw
ret ret
; reads current cluster into [dest] ; reads current cluster into [dest]
readc: ; load cluster number readc: ; load cluster number
mov ax, [clus] push ax
mov dx, [clus+2] push dx
; subtract the two dummy entries from FAT start ; subtract the two dummy entries from FAT start
sub ax, 2 sub ax, 2
@ -156,47 +153,82 @@ readc: ; load cluster number
; convert cluster number to sector number ; convert cluster number to sector number
; this is some cheapo multiplication with 2^n ; this is some cheapo multiplication with 2^n
mov ch, [sc] mov cl, [sc]
l02: shr cl, 1 l02: shr cl, 1
jz l02e jz l02e
clc clc
rcl dx, 1
rcl ax, 1 rcl ax, 1
rcl dx, 1
jmp l02 jmp l02
l02e: l02e:
; dx:ax is now sector num in data area ; dx:ax is now sector num in data area
call offd
mov bx, [dest]
mov cx, [sc] mov cx, [sc]
xor ch, ch xor ch, ch
call readp call readd
xchg bx, cx xchg bp, cx
mov cl, 5 mov cl, 5
sal bx, cl sal bp, cl
add [dest], bx add bx, bp
pop dx
pop ax
ret ret
loadf: call readc ; load cluster chain DX:AX to [dest]:0
load: mov bx, 0x07C0
lloop: call readc
call next call next
cmp word [clus+2], 0x0FFF cmp word dx, 0x0FFF
jne loadf jne lloop
ret ret
main: call loadf ; Search for first entry with matching fsattr
mov ax, [0x7C00] search: mov si, (0x7C00-0x20)
mov cx, [0x7C02] loop: add si, 0x20
int 3 ; check if entry is valid
mov al, [si]
; unallocated direntry
test al, al
jz end
; deleted files
cmp al, 0xE2
je loop
; check attr
mov al, [si+11]
and al, 0x5C
cmp al, ah
jne loop
ret
xor ah,ah main: mov ax, 2
int 0x16 xor dx, dx
int 0x19 call load
jmp hlt
; current cluster number ; search for an system directory
clus: dd 2 mov ah, 0x14
call search
jne end
mov ax, [si+0x1A]
mov dx, [si+0x14]
call load
mov ah, 0x04
call search
jne end
mov ax, [si+0x1A]
mov dx, [si+0x14]
call load
jmp 0:0x7C00
end: call msg
db "DIR", 0
jmp err
; segment register for data ; segment register for data
dest: dw 0x07c0 dest: dw 0x07c0