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
1 changed files with 76 additions and 44 deletions

View File

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