fat32 bootloader: implement directory recursing and kernel load
this is actually working now.
This commit is contained in:
parent
bbe006c9bc
commit
0b2a7e7b64
118
boot/fat32.asm
118
boot/fat32.asm
@ -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
|
||||
|
||||
pop bx
|
||||
|
||||
; get lower part of cluster number
|
||||
mov si, [clus]
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user