From 947f4b4a06bc214fa89ef3a8736be710bfe76e3d Mon Sep 17 00:00:00 2001 From: Matheus Date: Wed, 3 Aug 2022 23:38:56 -0300 Subject: [PATCH] initrd stub --- Makefile | 6 +- initrd/etc/test | 1 + src/arch/x86_64/main.c | 2 + src/fs/initrd.c | 147 ++++++++++++++++++++++++++++++++++++ src/include/kernel/initrd.h | 6 ++ 5 files changed, 159 insertions(+), 3 deletions(-) create mode 100644 initrd/etc/test create mode 100644 src/fs/initrd.c create mode 100644 src/include/kernel/initrd.h diff --git a/Makefile b/Makefile index 500725dc..123b0e4b 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CC=x86_64-elf-gcc TARGET=x86_64 SRCDIR=$(PWD)/src/ OBJDIR=$(PWD)/bin/ -ISO=$(PWD)/boot/$(TARGET)/iso/ +ISO=$(PWD)/boot/$(TARGET)/iso KERNEL=$(ISO)/kernel INITRD=$(ISO)/initrd rwildcard=$(foreach d,$(wildcard $(1:=/*)),$(call rwildcard,$d,$2) $(filter $(subst *,%,$2),$d)) @@ -29,9 +29,9 @@ $(KERNEL): srcdir $(KERNELSRCDEPS) kernel.ld $(CC) $(LDFLAGS) -o $@ $(call rwildcard,bin,*.o) $(INITRD): $(call rwildcard,initrd,*) - cd initrd;tar -cf $(INITRD) . + cd initrd;tar -cf $(INITRD) * -sysdisk.iso: $(ISO) +sysdisk.iso: $(ISO) $(INITRD) cp liminebg.bmp limine.cfg limine/limine.sys limine/limine-cd.bin limine/limine-cd-efi.bin $(ISO) xorriso -as mkisofs -b limine-cd.bin -no-emul-boot -boot-load-size 4 -boot-info-table --efi-boot limine-cd-efi.bin -efi-boot-part --efi-boot-image --protective-msdos-label $(ISO) -o sysdisk.iso diff --git a/initrd/etc/test b/initrd/etc/test new file mode 100644 index 00000000..70556506 --- /dev/null +++ b/initrd/etc/test @@ -0,0 +1 @@ +this is just a test diff --git a/src/arch/x86_64/main.c b/src/arch/x86_64/main.c index 026ca129..a4bfb6b4 100644 --- a/src/arch/x86_64/main.c +++ b/src/arch/x86_64/main.c @@ -54,6 +54,8 @@ void kmain(){ if(vfs_mount(vfs_root(), NULL, "", "tmpfs", 0, NULL)) _panic("Failed to mount tmpfs", 0); + + initrd_parse(); _panic("End of kmain()", 0); diff --git a/src/fs/initrd.c b/src/fs/initrd.c new file mode 100644 index 00000000..2313cc07 --- /dev/null +++ b/src/fs/initrd.c @@ -0,0 +1,147 @@ +#include +#include +#include +#include +#include +#include + +#define TAR_BLOCKSIZE 512 + +static volatile struct limine_module_request modreq = { + .id = LIMINE_MODULE_REQUEST, + .revision = 0 +}; + +typedef struct{ + char name[100]; + char mode[8]; + char uid[8]; + char gid[8]; + char size[12]; + char modtime[12]; + char checksum[8]; + char type[1]; + char link[100]; + char indicator[6]; + char version[2]; + char uname[32]; + char gname[32]; + char devmajor[8]; + char devminor[8]; + char prefix[155]; +} tar_block; + +typedef struct{ + char name[256]; + short mode; + short gid; + short uid; + size_t size; + size_t modtime; + short checksum; + short type; + char link[101]; + char indicator[6]; + char version[2]; + short devminor; + short devmajor; +} tar_entry; + +static volatile size_t convert(char* buff, size_t len){ + size_t result = 0; + while(len--){ + result *= 8; + result += *buff - '0'; + buff++; + } + + return result; +} + +static volatile void buildentry(tar_entry* entry, void* addr){ + + tar_block* block = (tar_block*)addr; + + if(block->name[99]){ + if(block->prefix[154]){ + memcpy(entry->name, block->prefix, 154); + } + else{ + strcpy(entry->name, block->prefix); + } + + memcpy(entry->name + strlen(entry->name), block->name, 99); + + } + else{ + + strcpy(entry->name, block->name); + + } + + entry->mode = convert(block->mode, 8); + entry->uid = convert(block->uid, 8); + entry->gid = convert(block->gid, 8); + entry->size = convert(block->size, 11); + entry->modtime = convert(block->modtime, 11); + entry->checksum = convert(block->checksum, 8); + entry->type = convert(block->type, 1); + + if(block->link[99]){ + memcpy(entry->link, block->link, 100); + } + else{ + strcpy(entry->link, block->link); + } + + memcpy(entry->indicator, block->indicator, 6); + memcpy(entry->version, block->version, 2); + entry->devmajor = convert(block->devmajor, 8); + entry->devminor = convert(block->devminor, 8); + + + +} + +void initrd_parse(){ + + if(!modreq.response) + _panic("No modules passed to limine!", 0); + + size_t modcount = modreq.response->module_count; + struct limine_file** modules = modreq.response->modules; + struct limine_file* initrd = NULL; + + for(size_t i = 0; i < modcount; ++i){ + if(!strcmp(modules[i]->path, "/initrd")){ + initrd = modules[i]; + break; + } + } + + if(!initrd) _panic("No initrd found!", 0); + + printf("Found initrd at %p with size %lu\n", initrd->address, initrd->size); + + void* addr = initrd->address; + + tar_entry entry; + + memset(entry.name, 0, 256); + memset(entry.link, 0, 101); + + for(;;){ + + buildentry(&entry, addr); + + + if(strncmp("ustar", entry.indicator, 5)) + break; + + printf("NAME: %s SIZE: %lu\n", entry.name, entry.size); + + addr += TAR_BLOCKSIZE + TAR_BLOCKSIZE * (entry.size / TAR_BLOCKSIZE) + (entry.size % TAR_BLOCKSIZE > 0 ? TAR_BLOCKSIZE : 0); + + } + +} diff --git a/src/include/kernel/initrd.h b/src/include/kernel/initrd.h new file mode 100644 index 00000000..2b132ec6 --- /dev/null +++ b/src/include/kernel/initrd.h @@ -0,0 +1,6 @@ +#ifndef _INITRD_H_INCLUDE +#define _INITRD_H_INCLUDE + +void initrd_parse(); + +#endif