From babf3897f4d3dda277c3de3ad2acf11c9f0d2a09 Mon Sep 17 00:00:00 2001 From: Alexander Myltsev Date: Tue, 13 Dec 2022 00:50:28 +0300 Subject: [PATCH] Add fs.c. --- Makefile | 3 ++- drivers/ata.h | 3 +-- fs/fs.c | 39 +++++++++++++++++++++++++++++++++++++++ fs/fs.h | 3 ++- kernel.c | 10 +++++++--- string.c | 12 ++++++++++++ string.h | 1 + 7 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 fs/fs.c diff --git a/Makefile b/Makefile index 351c481..d0e184e 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,8 @@ image.bin: mbr.bin fs.img cat $^ >$@ kernel.bin: kernel.o console.o drivers/vga.o drivers/keyboard.o \ - string.o drivers/ata.o cpu/vectors.o cpu/idt.o cpu/gdt.o drivers/uart.o + string.o drivers/ata.o cpu/vectors.o cpu/idt.o cpu/gdt.o drivers/uart.o \ + fs/fs.o $(LD) $(LDFLAGS) -o $@ -Ttext 0x1000 $^ %.o: %.c diff --git a/drivers/ata.h b/drivers/ata.h index 3d5b3d6..67aea2f 100644 --- a/drivers/ata.h +++ b/drivers/ata.h @@ -1,5 +1,4 @@ #pragma once #include -void read_sectors_ATA_PIO(uint32_t target_address, uint32_t LBA, uint8_t sector_count); -void write_sectors_ATA_PIO(uint32_t LBA, uint8_t sector_count, uint32_t* bytes); +void read_sectors_ATA_PIO(void* target_address, uint32_t LBA, uint8_t sector_count); diff --git a/fs/fs.c b/fs/fs.c new file mode 100644 index 0000000..6a5c74a --- /dev/null +++ b/fs/fs.c @@ -0,0 +1,39 @@ +#include "fs.h" +#include "../string.h" +#include "../drivers/ata.h" + +enum { + fs_start = 1, // sector where the FS starts +}; + +int stat(const char* name, struct stat *buf) { + struct dir dir; + read_sectors_ATA_PIO(&dir, fs_start, 1); + for (int i = 0; i < ents_in_dir; ++i) { + struct dirent *e = &dir.entries[i]; + if (!strncmp(e->name, name, sizeof(e->name))) { + buf->size = e->size_bytes; + buf->reserved[0] = e->offset_sectors; + return 0; + } + } + return -1; +} + +/* Find file by name and read it into buffer with size bufsize. + * At most (bufsize & -512) bytes will be read. + * Return number of bytes read or -1 on failure. */ +int read_file(const char* name, void* buf, uint32_t bufsize) { + struct stat statbuf; + if (stat(name, &statbuf) != 0) { + return -1; + } + uint32_t sector = fs_start + statbuf.reserved[0]; + while (bufsize >= sector_size) { + read_sectors_ATA_PIO(buf, sector, 1); + sector++; + bufsize -= sector_size; + buf += sector_size; + } + return 0; +} diff --git a/fs/fs.h b/fs/fs.h index 8de61a3..67f01a2 100644 --- a/fs/fs.h +++ b/fs/fs.h @@ -21,6 +21,7 @@ size is in bytes, name is 0-terminated. enum { sector_size = 512, + ents_in_dir = 15, }; struct dirent { @@ -32,7 +33,7 @@ struct dirent { struct dir { char reserved[32]; - struct dirent entries[15]; + struct dirent entries[ents_in_dir]; }; struct stat { diff --git a/kernel.c b/kernel.c index 430c8d5..a7b3ec2 100644 --- a/kernel.c +++ b/kernel.c @@ -8,6 +8,7 @@ asm(".asciz \"kernel start\""); #include "drivers/ata.h" #include "drivers/misc.h" #include "drivers/uart.h" +#include "fs/fs.h" void _start() { load_gdt(); @@ -15,13 +16,16 @@ void _start() { uartinit(); load_idt(); sti(); - char buf[512]; + char buf[4096 + 512]; vga_clear_screen(); printk("YABLOKO\n"); - read_sectors_ATA_PIO((uint32_t)buf, 10, 1); - printk(buf); + if (read_file("kernel.bin", buf, sizeof(buf)) == 0) { + printk(buf + 4096); + } else { + printk("failed to read file\n"); + } while (1) { asm("hlt"); diff --git a/string.c b/string.c index bb71bff..99e1171 100644 --- a/string.c +++ b/string.c @@ -14,3 +14,15 @@ void kmemmove(char* dst, char* src, size_t size) { } } } + +int strncmp(const char* s1, const char* s2, size_t size) { + while (size && *s1 && *s2 && *s1 == *s2) { + size--; + s1++; + s2++; + } + if (!size) { + return 0; + } + return (unsigned char)(*s1) - (unsigned char)(*s2); +} diff --git a/string.h b/string.h index 9d8b0de..584f7d7 100644 --- a/string.h +++ b/string.h @@ -3,3 +3,4 @@ typedef unsigned size_t; void kmemmove(char* dst, char* src, size_t size); +int strncmp(const char* s1, const char* s2, size_t size);