From 40d670386a18565c3daa345f34d202131798179b Mon Sep 17 00:00:00 2001 From: Furkan Mudanyali Date: Wed, 27 Jul 2022 05:49:06 +0300 Subject: [PATCH] Initial TAR filesystem support --- fs/rock.txt | 22 ++++++++++++ iso.sh | 3 ++ kernel/Makefile | 1 + kernel/include/rockos/rockos.h | 6 +--- kernel/include/rockos/vfs.h | 64 ++++++++++++++++++++++++++++++++++ kernel/rockos/kernel.c | 32 ++++++++--------- kernel/rockos/paging.c | 3 ++ kernel/rockos/vfs.c | 56 +++++++++++++++++++++++++++++ 8 files changed, 164 insertions(+), 23 deletions(-) create mode 100644 fs/rock.txt create mode 100644 kernel/include/rockos/vfs.h create mode 100644 kernel/rockos/vfs.c diff --git a/fs/rock.txt b/fs/rock.txt new file mode 100644 index 0000000..126bd28 --- /dev/null +++ b/fs/rock.txt @@ -0,0 +1,22 @@ + ````^,:;;;I><~~+; + `````^^:l!!!>+-????< + .^```^^^^,li>~_?][}}}}[. + ^````^^^`,I!<_]}}{{{1{1] + `'''``^^^`:!i><_]}}}{11)|: + ''''''```^,!~_?{{[[}}[}}{)- + .`..''''`'`:l>+--}tf|)1[]})| + `^`I`...''''',-?+_{/|(\rn|(|\t\ + i`'''.'''''^I[[:~zrumdn[]>ccfff + ^l~`.....'`;>_l"_JcYpmf,"[#&hwQ. + .[?'.....'"I!!li_|nnt];`^]M$&kU + .^..'''.':i<<+_?}]>I;"``lzpk*" + ..`.'''..:+]]]]?_lIIi<,.^"'"i-/Y. + '``'...'^,:,^``"l:I)]:!jYU' + '``'...`^'''..'^;+(|+|rLL] + ''`'. .``... .`:!+]||CqCt + ''`^`...'' '"~]?)/frUOp" + ``'^"^`'''. ."<+_{|\xUQmkx + ^`'`^"""^`'..'i+I:_})nUQ0O^ +^`''`",:::::^'^l isodir/boot/grub/grub.cfg << EOF menuentry "rockOS" { multiboot /boot/rockos.kernel + module /boot/rockos.initrd } EOF "${GRUB_MKRESCUE}" -o rockos.iso isodir diff --git a/kernel/Makefile b/kernel/Makefile index da37e98..225cae9 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -35,6 +35,7 @@ rockos/kheap.o \ rockos/paging.o \ rockos/keyboard.o \ rockos/timer.o \ +rockos/vfs.o \ OBJS=\ $(ARCHDIR)/boot/crti.o \ diff --git a/kernel/include/rockos/rockos.h b/kernel/include/rockos/rockos.h index 6fdd441..c3bf5d8 100644 --- a/kernel/include/rockos/rockos.h +++ b/kernel/include/rockos/rockos.h @@ -24,8 +24,4 @@ static inline void panic(char* str) { asm("cli;hlt"); } -static inline void assert(uint32_t val) { - if(!val) { - panic("ASSERTION FAILED!"); - } -} \ No newline at end of file +#define assert(val) ((val) ? (void)0: (printf("ASSERTION FAILED, " __FILE__ ":%d: " #val "\n", __LINE__), panic(""))) \ No newline at end of file diff --git a/kernel/include/rockos/vfs.h b/kernel/include/rockos/vfs.h new file mode 100644 index 0000000..aa1cd2f --- /dev/null +++ b/kernel/include/rockos/vfs.h @@ -0,0 +1,64 @@ +/** + * VFS section header of rockOS + * Copyright (C) 2022 Furkan Mudanyali + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, _either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _ROCKOS_VFS_H +#define _ROCKOS_VFS_H + +#define FS_FILE 1 +#define FS_DIR 2 +#define FS_CHARDEV 3 +#define FS_BLOCKDEV 4 +#define FS_PIPE 5 +#define FS_SYMLINK 6 +#define FS_MOUNTPOINT 8 + +#include + +#define F_REGULAR 0 +#define F_NORMAL '0' +#define F_HLINK '1' +#define F_SYMLINK '2' +#define F_CHARDEV '3' +#define F_BLKDEV '4' +#define F_DIR '5' +#define F_FIFO '6' +#define F_CONT '7' + +typedef struct { + char filename[100]; // Filename + char mode[8]; // File mode + char uid[8]; // User ID + char gid[8]; // Group ID + char size[12]; // File size in bytes in octal string + char mtime[12]; // Modified time in UNIX Timestamp in octal string + char chksum[8]; // Checksum + char typeflag[1]; // File type + char linkname[100]; // Name of linked file + char magic[8]; // "ustar\000" +} TarHeader; + +typedef struct { + TarHeader* header; + uint32_t* data; +} Tar; + +uint32_t TarGetSize(const char*); + +uint32_t TarParse(uint32_t); + +#endif \ No newline at end of file diff --git a/kernel/rockos/kernel.c b/kernel/rockos/kernel.c index 28849f3..329cba9 100644 --- a/kernel/rockos/kernel.c +++ b/kernel/rockos/kernel.c @@ -25,12 +25,13 @@ #include #include #include +#include #include #include extern char _rockos_start, _rockos_end; - -static multiboot_info_t* multiboot_info; +multiboot_info_t* multiboot_info; +Tar* files; void bootloader_init(multiboot_info_t* mbd, unsigned int magic) { /* Make sure the magic number matches for memory mapping*/ @@ -46,12 +47,6 @@ void bootloader_init(multiboot_info_t* mbd, unsigned int magic) { } void kernel_main() { - printf("Hello, kernel World!\n"); - printf("String test: %s\n", "HELLOOOOO"); - printf("Float test: %.10f\n", 0.123456789); - printf("Int test: %d\n", 747474); - printf("Hex test: 0x%x\n", 0xDEADBEEF); - printf("And now for 0.1 + 0.2...... which is: %.17f\n", 0.1 + 0.2); initialize_keyset(); outb(0x70, 0x0); // Seconds @@ -65,8 +60,6 @@ void kernel_main() { min = (min & 0x0F) + ((min / 16) * 10); hour = ((hour & 0x0F) + (((hour & 0x70) / 16) * 10)) | (hour & 0x80); printf("Time: %02d:%02d:%02d UTC+3\n", (hour + 3) % 24, min, sec); - - printf("RockOS Start: %#08X, RockOS End: %#08X\n", &_rockos_start, &_rockos_end); for(multiboot_uint32_t i = 0; i < multiboot_info->mmap_length; i += sizeof(multiboot_memory_map_t)) { multiboot_memory_map_t* mmmt = @@ -80,14 +73,17 @@ void kernel_main() { } } - uint32_t a = kmalloc(8); - uint32_t b = kmalloc(8); - uint32_t c = kmalloc(8); - printf("A: %#08X B: %#08X C: %#08X\n",a,b,c); - kfree(c); - kfree(b); - uint32_t d = kmalloc(8); - printf("D: %#08X\n", d); + files = kmalloc(256 * sizeof(Tar)); + uint32_t initrd_location = *((uint32_t*)multiboot_info->mods_addr); + + printf("Initrd location: %#08X\n", initrd_location); + uint32_t fileCount = TarParse(initrd_location); + + printf("Found files: %d\n", fileCount); + for(uint32_t i = 0; i < fileCount; ++i) { + printf("Filename: %s\n", files[i].header->filename); + printf("%s\n", files[i].data); + } unsigned char key; for(;;) { diff --git a/kernel/rockos/paging.c b/kernel/rockos/paging.c index 5983dcb..9ab2e9f 100755 --- a/kernel/rockos/paging.c +++ b/kernel/rockos/paging.c @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -31,6 +32,7 @@ uint32_t* frames; uint32_t nframes; extern uint32_t start_addr; +extern multiboot_info_t* multiboot_info; extern Heap* kheap; void FrameSet(uint32_t frame_addr) { @@ -114,6 +116,7 @@ void paging_switch_dir(PageDirectory* dir) { } void paging_init() { + start_addr = *(uint32_t*)(multiboot_info->mods_addr + 4); printf("Initializing paging.\n"); uint32_t page_end_mem = 0x1000000; nframes = page_end_mem / 0x1000; diff --git a/kernel/rockos/vfs.c b/kernel/rockos/vfs.c new file mode 100644 index 0000000..c2a9e53 --- /dev/null +++ b/kernel/rockos/vfs.c @@ -0,0 +1,56 @@ +/** + * VFS section of rockOS + * Copyright (C) 2022 Furkan Mudanyali + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, _either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +extern Tar* files; + +uint32_t TarGetSize(const char* in) { + uint32_t size = 0; + uint32_t count = 1; + for(uint32_t i = 11; i > 0; i--, count *= 8) { + size += ((in[i - 1] - '0') * count); + } + return size; +} + +uint32_t TarParse(uint32_t addr) { + uint32_t i; + for(i = 0;; i++) { + TarHeader* header = (TarHeader*)addr; + + if(memcmp("ustar", header->magic, 5) && + memcmp("ustar\0", header->magic, 6) && + memcmp("ustar\000", header->magic, 8)) { + break; + } + + uint32_t size = TarGetSize(header->size); + files[i].header = addr; + files[i].data = addr + 512; + + addr += ((size / 512) + 1) * 512; + if(size % 512) { + addr += 512; + } + } + return i; +} \ No newline at end of file