From 3349ec20ae5e1c5c628133c456ca6d424e69e0a6 Mon Sep 17 00:00:00 2001 From: d0p1 Date: Mon, 2 Sep 2024 15:12:19 +0200 Subject: [PATCH] feat(boot): load kernel from StupidFS --- boot/loader/loader.asm | 10 +++ boot/loader/stpdfs.inc | 164 +++++++++++++++++++++++++++++++++++------ 2 files changed, 152 insertions(+), 22 deletions(-) diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index 39a92e6..363f31c 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -84,7 +84,17 @@ _start: mov si, szKernelStpdfsFile 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 diff --git a/boot/loader/stpdfs.inc b/boot/loader/stpdfs.inc index feacb75..f5d722b 100644 --- a/boot/loader/stpdfs.inc +++ b/boot/loader/stpdfs.inc @@ -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 { .inode dw ? .nlink dw ? @@ -14,16 +17,19 @@ struc Inode { } DEFN Inode - ;; Struct: dirent -struc dirent { +STPDFS_INODE_PER_BLOCK equ STPDFS_BLOCK_SIZE / sizeof.Inode + + ;; Struct: DirEntry +struc DirEntry { .inum dd ? .name db STPDFS_NAME_MAX dup(?) } -DEFN dirent +DEFN DirEntry ;; Function: stpdfs_load_rootdir ;; ;; Out: + ;; stpdfs_load_rootdir: ; read first inode mov ax, DISK_BUFFER/0x10 @@ -44,10 +50,48 @@ stpdfs_load_rootdir: mov ax, DISK_BUFFER/0x10 mov es, ax - + xor bx, bx 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 @@ -56,47 +100,123 @@ stpdfs_load_rootdir: ;; In: ;; SI - filename ;; + ;; Out: + ;; EAX - kernel inode stpdfs_search: 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 ;; Function: stpdfs_copy_data ;; ;; In: - ;; ES - Buffer + ;; ES:BX - buffer + ;; stpdfs_copy_data: xor edx, edx - mov bx, es 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 shl eax, 2 - add eax, dword [inode_cache + Inode.zones] + add eax, inode_cache + Inode.zones + mov eax, [eax] push edx push ebx mov cx, 1 - xor bx, bx call disk_read_sectors pop ebx pop edx - mov ax, es - add ax, 512 - mov es, ax + add ebx, STPDFS_BLOCK_SIZE inc edx - cmp edx, 8 - jbe @b + cmp edx, 7 + jb @b .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: ret