#include "initrd.h" #include "tar.h" #include "string.h" #include "commandline.h" #include "memory.h" #include "print.h" #include "klib/rbtree.h" #include "klib/hash.h" #include "boot.h" static rbtree_t 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 tar_block *sector = (struct tar_block*)module->addr; while(true) { tar_header_t *header = (tar_header_t*)sector; if(header->name[0] == 0) break; initrd_file_t file_tmp; initrd_file_t *file = rbtree_insert( &s_initrd_files, string_hash(header->name), &file_tmp); *file = (initrd_file_t){ .header = header, .name = header->name, .size = s_tar_oct_dec(header->size), .data = §or[1] }; kdbgf("File %s size %i\n", file->name, file->size); sector = §or[(file->size / 512) + 1]; if(file->size % 512 > 0) sector = §or[1]; } } initrd_file_t * ird_getfile(const char *path) { initrd_file_t *file = rbtree_find(&s_initrd_files, string_hash(path)); return file; } void initrd_setup(void) { const char *initrd_path = cmdline_get("initrd"); if(initrd_path == 0) { kerrf("No initrd loaded!\n"); return; } kdbgf("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; } rbtree_new(&s_initrd_files, initrd_file_t); s_initrd_parse(initrd_module); }