aboutsummaryrefslogtreecommitdiff
path: root/kernel/initrd.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/initrd.c')
-rw-r--r--kernel/initrd.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/kernel/initrd.c b/kernel/initrd.c
index c05e77d..4706fe8 100644
--- a/kernel/initrd.c
+++ b/kernel/initrd.c
@@ -63,16 +63,48 @@ __kernel int get_task_id_from_name(const char *const name)
return TASK_UNKNOWN;
}
-__kernel void extract_elf(int task_id, const char *const addr, size_t size)
+__kernel void ensure_elf_format(const unsigned char *const addr)
+{
+ if (addr[0] != 0x7F || memcmp(&addr[1], "ELF", 3) != 0) {
+ die("Bad ELF format\n");
+ }
+ if (addr[4] != 2) {
+ die("64-bit format is mandatory\n");
+ }
+ if (addr[5] != 1) {
+ die("Little-endian only\n");
+ }
+}
+
+struct exec_header {
+ uint64_t e_entry;
+ uint64_t e_phoff;
+ uint16_t e_phnum;
+ uint16_t e_phentsize;
+};
+
+// TODO
+__kernel void extract_elf(int task_id, const unsigned char *const addr, size_t size)
{
__unused(task_id);
- __unused(addr);
__unused(size);
- // TODO
+ ensure_elf_format(addr);
+
+ /* struct exec_header header = { */
+ /* .e_entry = (unsigned long long)addr[0x18], */
+ /* .e_phoff = (uint64_t)addr[0x20], */
+ /* .e_phentsize = (uint16_t)addr[0x36], */
+ /* .e_phnum = (uint16_t)addr[0x38], */
+ /* }; */
+
+#ifdef __KERNEL__
+ tasks[task_id].addr = (const void *)addr;
+ tasks[task_id].entry_offset = (uint64_t)addr[0x18];
+#endif
}
-__kernel void extract_initrd(const char *const initrd_addr, uint64_t size)
+__kernel void extract_initrd(const unsigned char *const initrd_addr, uint64_t size)
{
char buffer[BUFFER_SIZE];
uint64_t name_size, file_size, padding, base = 0;