blob: 30d690ed75dfff29c41f3de0553aa48bfffe972d [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
swissChili480f1762021-07-26 22:17:34 -070034struct fs_node *initrd_finddir(struct fs_node *node, char *name,
35 uint name_len)
swissChilic2e62ed2021-03-10 17:04:18 -080036{
37 if (node != &real_initrd)
38 return NULL;
39
40 for (int i = 0; i < num_initrd_files; i++)
41 {
swissChili480f1762021-07-26 22:17:34 -070042 if (strncmp(entries[i].name, name,
43 MIN(FS_MAX_NAME_LEN, name_len))
44 == 0)
45 {
swissChilic2e62ed2021-03-10 17:04:18 -080046 return &initrd_content[i];
swissChili480f1762021-07-26 22:17:34 -070047 }
swissChilic2e62ed2021-03-10 17:04:18 -080048 }
49 return NULL;
50}
51
52void initrd_open(struct fs_node *node)
53{
54}
55
56void initrd_close(struct fs_node *node)
57{
58}
59
60uint initrd_read(struct fs_node *node, size_t offset, size_t size, uchar *buffer)
61{
62 if (offset > node->size)
63 return 0;
64
65 size = MIN(size, node->size - offset);
swissChili480f1762021-07-26 22:17:34 -070066 memcpy(buffer, entries[node->dri_res_i].data, size);
swissChilic2e62ed2021-03-10 17:04:18 -080067
68 return size;
69}
70
71void init_initrd_vfs(uchar *data)
swissChilib7fe8992021-03-10 16:25:47 -080072{
73 memset(&real_initrd, 0, sizeof(real_initrd));
74
75 real_initrd.flags = FS_DIRECTORY;
swissChilic2e62ed2021-03-10 17:04:18 -080076 real_initrd.vtable = &initrd_v;
77
78 initrd_v.readdir = initrd_readdir;
79 initrd_v.finddir = initrd_finddir;
80 initrd_v.open = initrd_open;
81 initrd_v.close = initrd_close;
82 initrd_v.read = initrd_read;
83
84 // parse initrd
85 struct initrd_global_header *h = (struct initrd_global_header *)data;
86
87 if (h->magic != INITRD_MAGIC)
88 {
swissChili9bd74de2021-06-15 20:30:48 -070089 kprintf(ERROR "initrd magic is wrong: %x should be %x\n", h->magic,
swissChilic2e62ed2021-03-10 17:04:18 -080090 INITRD_MAGIC);
91 kpanic("initrd magic");
92 }
93
94 num_initrd_files = h->num_files;
95 initrd_content = malloc(sizeof(struct fs_node) * num_initrd_files);
96 entries = malloc(sizeof(struct initrd_fs_entry) * num_initrd_files);
97
98 // create fs_nodes for files
99 struct initrd_file_header *f =
100 (struct initrd_file_header *)(data +
101 sizeof(struct initrd_global_header));
102
103 for (int i = 0; i < num_initrd_files; i++)
104 {
105 uchar *data = (uchar *)((size_t)f + sizeof(struct initrd_file_header));
106
107 entries[i].data = data;
108 entries[i].name = f->name;
109 entries[i].size = f->size;
110
111 initrd_content[i] = (struct fs_node){
swissChili480f1762021-07-26 22:17:34 -0700112 .dri_res_i = i,
swissChilic2e62ed2021-03-10 17:04:18 -0800113 .flags = FS_FILE,
114 .mask = 0b101001001,
115 .uid = 0,
116 .gid = 0,
117 .size = f->size,
118 .vtable = &initrd_v,
119 .mount = NULL
120 };
121
122 memcpy(initrd_content[i].name, f->name, strlen(f->name));
123
124 f = (struct initrd_file_header *)((size_t)data + f->size);
125 }
126
127 // mount initrd to /dev/initrd/
128 if (fs_mount(&initrd, &real_initrd))
129 kpanic("Failed to mount initrd to /dev/initrd");
swissChilib7fe8992021-03-10 16:25:47 -0800130}