From a976854bc9ba1207fe21d72b8c43cd4e21e8be5e Mon Sep 17 00:00:00 2001 From: d0p1 Date: Thu, 29 Aug 2024 16:14:09 +0200 Subject: [PATCH] feat(tools): mkfs bootsector load loader --- tools/inspect/main.c | 4 +++ tools/mkfs/boot.asm | 85 +++++++++++++++++++++++++++++--------------- tools/tools/copy.c | 7 ++++ 3 files changed, 67 insertions(+), 29 deletions(-) diff --git a/tools/inspect/main.c b/tools/inspect/main.c index cb6b4fe..053243b 100644 --- a/tools/inspect/main.c +++ b/tools/inspect/main.c @@ -83,6 +83,10 @@ inspect(void) printf(" gid: %hx\n", ip->inode.gid); printf(" flags: %hx\n", ip->inode.flags); printf(" size: %u\n", ip->inode.size); + for (idx = 0; idx < 10; idx++) + { + printf(" zone[%d]: 0x%X\n", idx, ip->inode.zones[idx]); + } time = ip->inode.actime; printf(" actime: %s", ctime(&time)); time = ip->inode.modtime; diff --git a/tools/mkfs/boot.asm b/tools/mkfs/boot.asm index 7dd20ac..7556e32 100644 --- a/tools/mkfs/boot.asm +++ b/tools/mkfs/boot.asm @@ -1,11 +1,19 @@ [BITS 16] [ORG 0x7c00] + ; check reading reading media with lba + ; read 2 first block (superblock & inode) + ; validate that it's a StupidFS by checking magic + ; check if inode 2 is present (loader reside in inode 2) + ; get loader size + ; iterate direct zone and load data to LOADER_BASE + ; iterate double indirect and load data (in order to keep things simple we won't support loader > 69632 bytes) + LOADER_BASE equ 0x1000 DISK_BUFFER equ 0x8000 STPDFS_MAGIC equ 0x44505453 BLOCK_SIZE equ 512 - INODE_SIZE equ 34 + INODE_SIZE equ 0x46 INODE_ALLOCATED equ (1<<15) CR equ 0xD LF equ 0xA @@ -89,49 +97,63 @@ start: cmp eax, STPDFS_MAGIC jne .err_magic - ; inode 0 bad + ; inode 0 bad inode ; inode 1 root dir ; inode 2 is loader, let's keep things easy - mov ax, word [DISK_BUFFER + 512 + 0x46 * 2 + inode.flags] + mov ax, word [DISK_BUFFER + 512 + INODE_SIZE * 2 + inode.flags] and ax, INODE_ALLOCATED jz .err_no_loader - mov dword eax, [DISK_BUFFER + 512 + 0x46 * 2 + inode.size] ; size + mov dword eax, [DISK_BUFFER + 512 + INODE_SIZE * 2 + inode.size] ; size mov dword [uFsize], eax - xchg bx, bx + ; copy data to LOADER_BASE + mov ax, LOADER_BASE + mov es, ax - xor ecx, ecx + ; direct read xor edx, edx - mov eax, DISK_BUFFER + 0x46 * 2 + inode.zones ; first zone -.read_loop: - cmp dword ecx, [uFsize] +.direct_loop: + mov ax, es + movzx ecx, ax + sub ecx, LOADER_BASE + cmp ecx, [uFsize] + xchg bx, bx jg .all_read - -.zone_loop: - cmp edx, 7 - jb .zone_direct - -.zone_triple: - -.zone_double: - -.zone_indirect: - -.zone_direct: mov eax, edx - shr eax, 2 - add eax, DISK_BUFFER + 0x46 + 2 + inode.zones - + shl eax, 2 + add eax, DISK_BUFFER + 512 + INODE_SIZE * 2 + inode.zones + push edx + + ; copy block + mov eax, [eax] + mov cx, 1 + xor bx, bx + call disk_read_sectors + + pop edx + + mov ax, es + add ax, BLOCK_SIZE + mov es, ax inc edx -.end_zone: - add ecx, BLOCK_SIZE - jmp .read_loop + cmp edx, 8 + xchg bx, bx + jbe .direct_loop + +.indirect_read: + ; TODO + + .all_read: - + + ; jump to loader + xchg bx, bx jmp 0x0:LOADER_BASE + + .err_no_loader: mov si, szErrorNoLoader call bios_print @@ -140,6 +162,10 @@ start: mov si, szErrorNoLoader call bios_print jmp .end +.err_read: + mov si, szErrorRead + call bios_print + jmp .end .err_lba: mov si, szErrorLBA call bios_print @@ -160,6 +186,7 @@ bios_print: szErrorNoLoader: db "Loader not found", CR, LF, 0 szErrorBadMagic: db "Err: magic", CR, LF, 0 szErrorLBA: db "Err: LBA", CR, LF, 0 +szErrorRead: db "Err: read", CR, LF, 0 uFsize: dd 0 disk_read_sectors: @@ -171,7 +198,7 @@ disk_read_sectors: mov dl, [bpb.drive_num] mov ah, 0x42 int 0x13 - jc start.err_lba + jc start.err_read ret disk_packet: diff --git a/tools/tools/copy.c b/tools/tools/copy.c index c5c7d04..e99d681 100644 --- a/tools/tools/copy.c +++ b/tools/tools/copy.c @@ -1,3 +1,5 @@ +#include "libfs/inode.h" +#include #include #include #include @@ -67,6 +69,10 @@ do_copy(void) } ip = fs_inode_alloc(&super); + if (ip->valid == 0) + { + fs_inode_read(ip); + } ip->inode.mode = st.st_mode; ip->inode.uid = st.st_uid; ip->inode.gid = st.st_gid; @@ -74,6 +80,7 @@ do_copy(void) ip->inode.actime = st.st_atime; ip->inode.flags = STPDFS_INO_FLAG_ALOC; + fs_inode_update(ip); fp = fopen(src, "rb");