#include "initrd.h" #include "arch/x86_64/hal/obj.h" #include "proc/init.h" #include "jove.h" #include "lib/printf.h" #include "lib/tar.h" #include "lib/string.h" #include "hal/obj.h" #include "hal/memory.h" #include "sys/objdir.h" extern uintptr_t _initrd_module; PAGEALIGN jove_objdir_t s_initrd_objdir = { 0 }; #define CHECK_IF_INITRD(obj) \ if(obj_gettype(obj) != JOVE_OBJ_INITRD_FILE) { \ reterr(EBADOBJ); \ } const char* initrd_file_name(jove_owned_obj_t *obj) { CHECK_IF_INITRD(obj); struct tar_header *file = obj_deref(obj); return tar_filename(file); } size_t initrd_file_size(jove_owned_obj_t *obj) { CHECK_IF_INITRD(obj); struct tar_header *file = obj_deref(obj); return tar_filesize(file); } void* initrd_file_data(jove_owned_obj_t *obj) { CHECK_IF_INITRD(obj); union tar_block *file = obj_deref(obj); return &(file[1]); } jove_owned_obj_t* initrd_seek(jove_owned_obj_t *objdir, const char *path) { if(obj_gettype(objdir) != JOVE_OBJ_OBJDIR) { reterr(EBADOBJ); } for(size_t i = 0; i < OBJDIR_ENTRIES; i++) { jove_owned_obj_t *file_obj = objdir_getlocal(objdir, i); if(obj_gettype(file_obj) != JOVE_OBJ_INITRD_FILE) { goto loop_continue; } const char *filepath = initrd_file_name(file_obj); if(filepath == NULL) { goto loop_continue; } if(strncmp(path, filepath, strlen(filepath)+1) == 0) { return file_obj; } loop_continue: obj_release(file_obj); } return NULL; } void initrd_setup(void) { kprintf("Loading initrd from bootloader:\n"); { jove_owned_obj_t *initrd_objdir_obj = objdir_getlocal(_rootdir_obj, INIT_ROOTDIR_INITRD_I); obj_settype(initrd_objdir_obj, JOVE_OBJ_OBJDIR); obj_setvalue(initrd_objdir_obj, (uintmax_t)&s_initrd_objdir); size_t initrd_files = 0; union tar_block *block = phys_tovirt(_initrd_module); for(;;) { struct tar_header *header = &block->header; if(*header->filename == 0) break; size_t file_size = tar_filesize(header); kprintf("File: %s, Size: %i\n", tar_filename(header), file_size); { jove_owned_obj_t *initrd_file_obj = objdir_getlocal(initrd_objdir_obj, initrd_files++); obj_settype(initrd_file_obj, JOVE_OBJ_INITRD_FILE); obj_setvalue(initrd_file_obj, (uintmax_t)block); obj_release(initrd_file_obj); } block = &block[((file_size + 511) / 512) + 1]; } obj_release(initrd_objdir_obj); } }