Skip to content

Commit c53e45b

Browse files
committed
added initramfs parsing to hal
1 parent 88f4713 commit c53e45b

3 files changed

Lines changed: 119 additions & 0 deletions

File tree

include/stdbigos/error.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ typedef enum [[nodiscard]] {
1717
ERR_NOT_ENOUGH_MEMORY,
1818
ERR_REPEATED_INITIALIZATION,
1919
ERR_ALLOCATION_FAILED,
20+
ERR_DT_NODE_NOT_FOUND,
21+
ERR_DT_PROP_NOT_FOUND,
2022
} error_t;
2123

2224
#endif // !BIGOS_INCLUDE_STDBIGOS_ERROR

src/kernel/hal/include/initramfs.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef HAL_INITRAMFS
2+
#define HAL_INITRAMFS
3+
4+
#include "stdbigos/buffer.h"
5+
#include "stdbigos/error.h"
6+
7+
error_t hal_initramfs_read(const char* filename, buffer_t* buffOUT);
8+
9+
#endif // !HAL_INITRAMFS

src/kernel/hal/initramfs.c

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#include "hal/include/initramfs.h"
2+
3+
#include "dt/dt.h"
4+
#include "hal_internal.h"
5+
#include "stdbigos/buffer.h"
6+
#include "stdbigos/string.h"
7+
8+
/*
9+
* initramfs layout (big endian)
10+
*
11+
* u32 magic
12+
* u32 version
13+
* u16 - file_count
14+
*
15+
* u32 - offset (from the start of initramfs)
16+
* u32 - size
17+
* u8 - namesize
18+
* char[] - name
19+
* ...
20+
*
21+
* data blob
22+
* */
23+
24+
static error_t validate(buffer_t initramfs_buff) {
25+
const u32 INITRAMFS_MAGIC = 0xB16B00B5;
26+
u32 magic = 0;
27+
u32 version = 0;
28+
if (!buffer_read_u32_be(initramfs_buff, 0, &magic))
29+
return ERR_INVALID_MEMORY_REGION;
30+
if (magic != INITRAMFS_MAGIC)
31+
return ERR_INVALID_MEMORY_REGION;
32+
if (!buffer_read_u32_be(initramfs_buff, 4, &version))
33+
return ERR_INVALID_MEMORY_REGION;
34+
// TODO: Handle version
35+
return ERR_NONE;
36+
}
37+
38+
static error_t find_initramfs_buffer(buffer_t* buffOUT) {
39+
void* dtbptr = nullptr;
40+
if (ihal_get_dtb(&dtbptr) != ERR_NONE)
41+
return ERR_NOT_INITIALIZED;
42+
fdt_t fdt;
43+
(void)dt_init(dtbptr, &fdt); // This error is checkd on hal init
44+
dt_node_t initramfs_node;
45+
error_t err = dt_get_node_by_path(&fdt, "initramfs", &initramfs_node);
46+
if (err)
47+
return ERR_DT_NODE_NOT_FOUND;
48+
dt_prop_t initramfs_reg;
49+
err = dt_get_prop_by_name(&fdt, initramfs_node, "reg", &initramfs_reg);
50+
if (err)
51+
return ERR_DT_PROP_NOT_FOUND;
52+
return dt_get_prop_buffer(&fdt, initramfs_reg, buffOUT);
53+
}
54+
55+
typedef struct {
56+
u32 offset;
57+
u32 size;
58+
} file_header_t;
59+
60+
// TODO: Change filename to string_view
61+
static error_t find_file_by_name(const char* filename, buffer_t initramfs_buff, file_header_t* headerOUT) {
62+
u64 cursor = 8;
63+
u16 filecount = 0;
64+
if (!buffer_read_u16_be(initramfs_buff, cursor, &filecount))
65+
return ERR_INVALID_MEMORY_REGION;
66+
cursor += sizeof(u16);
67+
for (u16 i = 0; i < filecount; ++i) {
68+
if (!buffer_read_u32_be(initramfs_buff, cursor, &headerOUT->offset))
69+
return ERR_INVALID_MEMORY_REGION;
70+
cursor += sizeof(u32);
71+
if (!buffer_read_u32_be(initramfs_buff, cursor, &headerOUT->size))
72+
return ERR_INVALID_MEMORY_REGION;
73+
cursor += sizeof(u32);
74+
u64 file_name_size = 0; // This is of type u8 but buffer_t interface wants u64
75+
if (!buffer_read_u8(initramfs_buff, cursor, (u8*)&file_name_size))
76+
return ERR_INVALID_MEMORY_REGION;
77+
cursor += sizeof(u8);
78+
79+
buffer_t target_filename_buff = make_buffer(filename, strlen(filename));
80+
buffer_t filename_buff = make_buffer(initramfs_buff.data + cursor, file_name_size);
81+
cursor += file_name_size;
82+
83+
if (buffer_memcmp(target_filename_buff, filename_buff) == 0) {
84+
if (headerOUT->offset + headerOUT->size > initramfs_buff.size)
85+
return ERR_OUT_OF_BOUNDS;
86+
return ERR_NONE;
87+
}
88+
}
89+
headerOUT->size = 0;
90+
headerOUT->offset = 0;
91+
return ERR_NOT_FOUND;
92+
}
93+
94+
error_t hal_initramfs_read(const char* filename, buffer_t* buffOUT) {
95+
buffer_t initramfs_buff;
96+
error_t err = find_initramfs_buffer(&initramfs_buff);
97+
if (err)
98+
return err;
99+
err = validate(initramfs_buff);
100+
if (err)
101+
return err;
102+
file_header_t file_header;
103+
err = find_file_by_name(filename, initramfs_buff, &file_header);
104+
if (err)
105+
return err;
106+
*buffOUT = make_buffer(initramfs_buff.data + file_header.offset, file_header.size);
107+
return ERR_NONE;
108+
}

0 commit comments

Comments
 (0)