blob: 8fe0f01742844a9ba500871ccc321a677e2310a5 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
#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);
}
|