blob: bca0b50b916a7db5d786fcf10cbf31b181ca84e2 [file] [log] [blame]
swissChilic2e62ed2021-03-10 17:04:18 -08001#include "alloc.h"
swissChilib7fe8992021-03-10 16:25:47 -08002#include "io.h"
swissChilic2e62ed2021-03-10 17:04:18 -08003#include "kint.h"
4#include "log.h"
5#include "vfs.h"
6#include <initrd/initrd.h>
swissChili6c0519e2021-03-07 19:40:23 -08007
swissChilic2e62ed2021-03-10 17:04:18 -08008struct initrd_fs_entry
9{
10 char *name;
11 uchar *data;
12 uint size;
13};
swissChilib7fe8992021-03-10 16:25:47 -080014
swissChilic2e62ed2021-03-10 17:04:18 -080015static struct fs_node real_initrd;
16static struct fs_node *initrd_content = NULL;
17static struct initrd_fs_entry *entries = NULL;
18static struct fs_vtable initrd_v;
19static uint num_initrd_files = 0;
20
21bool initrd_readdir(struct fs_node *node, uint i, struct fs_dirent *out)
22{
23 if (node != &real_initrd)
24 return false;
25
26 if (i >= num_initrd_files)
27 return false;
28
29 memcpy(out->name, entries[i].name, strlen(entries[i].name) + 1);
30 out->inode = i;
31 return true;
32}
33
34struct fs_node *initrd_finddir(struct fs_node *node, char *name)
35{
36 if (node != &real_initrd)
37 return NULL;
38
39 for (int i = 0; i < num_initrd_files; i++)
40 {
41 if (strcmp(entries[i].name, name) == 0)
42 return &initrd_content[i];
43 }
44 return NULL;
45}
46
47void initrd_open(struct fs_node *node)
48{
49}
50
51void initrd_close(struct fs_node *node)
52{
53}
54
55uint initrd_read(struct fs_node *node, size_t offset, size_t size, uchar *buffer)
56{
57 if (offset > node->size)
58 return 0;
59
60 size = MIN(size, node->size - offset);
61 memcpy(buffer, entries[node->dri_res].data, size);
62
63 return size;
64}
65
66void init_initrd_vfs(uchar *data)
swissChilib7fe8992021-03-10 16:25:47 -080067{
68 memset(&real_initrd, 0, sizeof(real_initrd));
69
70 real_initrd.flags = FS_DIRECTORY;
swissChilic2e62ed2021-03-10 17:04:18 -080071 real_initrd.vtable = &initrd_v;
72
73 initrd_v.readdir = initrd_readdir;
74 initrd_v.finddir = initrd_finddir;
75 initrd_v.open = initrd_open;
76 initrd_v.close = initrd_close;
77 initrd_v.read = initrd_read;
78
79 // parse initrd
80 struct initrd_global_header *h = (struct initrd_global_header *)data;
81
82 if (h->magic != INITRD_MAGIC)
83 {
swissChili9bd74de2021-06-15 20:30:48 -070084 kprintf(ERROR "initrd magic is wrong: %x should be %x\n", h->magic,
swissChilic2e62ed2021-03-10 17:04:18 -080085 INITRD_MAGIC);
86 kpanic("initrd magic");
87 }
88
89 num_initrd_files = h->num_files;
90 initrd_content = malloc(sizeof(struct fs_node) * num_initrd_files);
91 entries = malloc(sizeof(struct initrd_fs_entry) * num_initrd_files);
92
93 // create fs_nodes for files
94 struct initrd_file_header *f =
95 (struct initrd_file_header *)(data +
96 sizeof(struct initrd_global_header));
97
98 for (int i = 0; i < num_initrd_files; i++)
99 {
100 uchar *data = (uchar *)((size_t)f + sizeof(struct initrd_file_header));
101
102 entries[i].data = data;
103 entries[i].name = f->name;
104 entries[i].size = f->size;
105
106 initrd_content[i] = (struct fs_node){
107 .dri_res = i,
108 .flags = FS_FILE,
109 .mask = 0b101001001,
110 .uid = 0,
111 .gid = 0,
112 .size = f->size,
113 .vtable = &initrd_v,
114 .mount = NULL
115 };
116
117 memcpy(initrd_content[i].name, f->name, strlen(f->name));
118
119 f = (struct initrd_file_header *)((size_t)data + f->size);
120 }
121
122 // mount initrd to /dev/initrd/
123 if (fs_mount(&initrd, &real_initrd))
124 kpanic("Failed to mount initrd to /dev/initrd");
swissChilib7fe8992021-03-10 16:25:47 -0800125}