feat(boot): load kernel from StupidFS

This commit is contained in:
d0p1 🏳️‍⚧️ 2024-09-02 15:12:19 +02:00
parent e5a7a87a58
commit 3349ec20ae
2 changed files with 152 additions and 22 deletions

View file

@ -84,7 +84,17 @@ _start:
mov si, szKernelStpdfsFile mov si, szKernelStpdfsFile
call stpdfs_search call stpdfs_search
jc .error_not_found
call stpdfs_read_inode
mov ebx, dword [inode_cache + Inode.size]
mov [uKernelSize], ebx
mov ax, KERNEL_PRELOAD/0x10
mov es, ax
xor bx, bx
call stpdfs_copy_data
jmp .skip_fat jmp .skip_fat

View file

@ -1,6 +1,9 @@
STPDFS_NAME_MAX = 28 ;; File: stpdfs.inc
;; Struct: inode STPDFS_BLOCK_SIZE = 512
STPDFS_NAME_MAX = 28
;; Struct: Inode
struc Inode { struc Inode {
.inode dw ? .inode dw ?
.nlink dw ? .nlink dw ?
@ -14,16 +17,19 @@ struc Inode {
} }
DEFN Inode DEFN Inode
;; Struct: dirent STPDFS_INODE_PER_BLOCK equ STPDFS_BLOCK_SIZE / sizeof.Inode
struc dirent {
;; Struct: DirEntry
struc DirEntry {
.inum dd ? .inum dd ?
.name db STPDFS_NAME_MAX dup(?) .name db STPDFS_NAME_MAX dup(?)
} }
DEFN dirent DEFN DirEntry
;; Function: stpdfs_load_rootdir ;; Function: stpdfs_load_rootdir
;; ;;
;; Out: ;; Out:
;;
stpdfs_load_rootdir: stpdfs_load_rootdir:
; read first inode ; read first inode
mov ax, DISK_BUFFER/0x10 mov ax, DISK_BUFFER/0x10
@ -44,10 +50,48 @@ stpdfs_load_rootdir:
mov ax, DISK_BUFFER/0x10 mov ax, DISK_BUFFER/0x10
mov es, ax mov es, ax
xor bx, bx
call stpdfs_copy_data call stpdfs_copy_data
xchg bx, bx ret
;; Function: stpdfs_read_inode
;;
;; copy selected inode from file system to `inode_cache`
;;
;; In:
;; EAX - inum
;;
stpdfs_read_inode:
; get block where inode is located
xor edx, edx
mov ecx, STPDFS_INODE_PER_BLOCK
div ecx
add eax, 2
; read block
push edx
push eax
mov ax, DISK_BUFFER/0x10
mov es, ax
pop eax
mov cx, 1
xor bx, bx
call disk_read_sectors
pop edx
; copy to inode cache
mov eax, edx
mov cl, sizeof.Inode
mul cl
movzx esi, ax
add esi, DISK_BUFFER
xor ax, ax
mov es, ax
mov ecx, sizeof.Inode
mov edi, inode_cache
rep movsb
ret ret
@ -56,47 +100,123 @@ stpdfs_load_rootdir:
;; In: ;; In:
;; SI - filename ;; SI - filename
;; ;;
;; Out:
;; EAX - kernel inode
stpdfs_search: stpdfs_search:
clc ; clear carry flag clc ; clear carry flag
xor ax, ax
mov es, ax
xor ecx, ecx
.search_loop:
cmp ecx, dword [inode_cache + Inode.size]
jge .search_end
push ecx
; check if inum != 0
mov eax, DISK_BUFFER
add eax, ecx
mov edx, [eax]
or edx, edx
jz .search_next
; compare filename
mov edi, eax
add edi, 4
push si
.strcmp:
mov al, [si]
cmpsb
jne .strcmp_not_equal
or al, al
jz .kernel_found
jmp .strcmp
.strcmp_not_equal:
pop si
.search_next:
pop ecx
add ecx, sizeof.DirEntry
jmp .search_loop
.search_end:
stc
ret
.kernel_found:
pop si
pop ecx
mov eax, edx
clc
ret ret
;; Function: stpdfs_copy_data ;; Function: stpdfs_copy_data
;; ;;
;; In: ;; In:
;; ES - Buffer ;; ES:BX - buffer
;;
stpdfs_copy_data: stpdfs_copy_data:
xor edx, edx xor edx, edx
mov bx, es
movzx ebx, bx movzx ebx, bx
@@:
mov ax, es
movzx ecx, ax
sub ecx, ebx
cmp ecx, dword [inode_cache + Inode.size]
jg .all_read
;; read direct
@@:
cmp ebx, dword [inode_cache + Inode.size]
jg .all_read
mov eax, edx mov eax, edx
shl eax, 2 shl eax, 2
add eax, dword [inode_cache + Inode.zones] add eax, inode_cache + Inode.zones
mov eax, [eax]
push edx push edx
push ebx push ebx
mov cx, 1 mov cx, 1
xor bx, bx
call disk_read_sectors call disk_read_sectors
pop ebx pop ebx
pop edx pop edx
mov ax, es add ebx, STPDFS_BLOCK_SIZE
add ax, 512
mov es, ax
inc edx inc edx
cmp edx, 8 cmp edx, 7
jbe @b jb @b
.indirect_read: .indirect_read:
push ebx
mov ax, es
push ax
mov ax, DISK_BUFFER/0x10
mov es, ax
mov eax, dword [inode_cache + Inode.zones + 28]
mov cx, 1
xor bx, bx
call disk_read_sectors
pop ax
mov es, ax
pop ebx
xor edx, edx
@@:
cmp ebx, dword [inode_cache + Inode.size]
jg .all_read
mov eax, edx
shl eax, 2
add eax, DISK_BUFFER
mov eax, [eax]
mov cx, 1
push edx
call disk_read_sectors
pop edx
add ebx, STPDFS_BLOCK_SIZE
inc edx
cmp edx, 128
jbe @b
.all_read: .all_read:
ret ret