#include "initrd.h" #include "lib/string.h" #include "io/log.h" #include "boot/boot.h" #include "boot/cmdline.h" #include "mem/memory.h" struct SlabCache s_initrd_cache; struct SLinkedList s_initrd_files; static size_t s_tar_oct_dec(const char *oct) { size_t value = 0; while(*oct != 0) { value *= 8; value += (*oct) - '0'; oct++; } return value; } static void s_initrd_parse(struct BootModule *module) { struct TARSector *sector = (struct TARSector*)module->addr; while(true) { struct TARHeader *header = (struct TARHeader*)sector; if(header->name[0] == 0) break; struct InitrdFile *file = mem_slab_alloc(&s_initrd_cache); *file = (struct InitrdFile){ .header = header, .name = header->name, .size = s_tar_oct_dec(header->size), .data = §or[1] }; klogf("File %s size %i\n", file->name, file->size); sll_push(&s_initrd_files, file); sector = §or[(file->size / 512) + 1]; if(file->size % 512 > 0) sector = §or[1]; } } struct InitrdFile * ird_getfile(const char *path) { for(struct SLLNode *node = s_initrd_files.head; node != NULL; node = node->next) { struct InitrdFile *file = (struct InitrdFile*)node; if(strcmp(file->name, path) == 0) return file; } return NULL; } struct SLinkedList * ird_getfiles(void) { return &s_initrd_files; } void initrd_setup(void) { const char *initrd_path = cmdline_get("initrd"); if(initrd_path == 0) { klogf("No initrd loaded!\n"); return; } klogf("Initrd located in module path %s\n", initrd_path); struct BootModule *initrd_module = NULL; for(size_t i = 0; i < boot_module_count; i++) { struct BootModule *module = &boot_modules[i]; if(strcmp(module->path, initrd_path) == 0) { initrd_module = module; break; } } if(initrd_module == NULL) { klogf("Initrd not found in modules!\n"); return; } sll_new(&s_initrd_files, sizeof(struct InitrdFile)); mem_slabcache_new(&s_initrd_cache, "initrd files", sizeof(struct InitrdFile)); s_initrd_parse(initrd_module); }