blob: f2192431a359267ce4aed72e022384f650efb51d (
plain) (
tree)
|
|
#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);
}
|