aboutsummaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/initrd.c135
1 files changed, 0 insertions, 135 deletions
diff --git a/kernel/initrd.c b/kernel/initrd.c
deleted file mode 100644
index 62a4e20..0000000
--- a/kernel/initrd.c
+++ /dev/null
@@ -1,135 +0,0 @@
-#include <fbos/init.h>
-#include <fbos/sched.h>
-#include <fbos/printk.h>
-#include <fbos/string.h>
-
-#define BUFFER_SIZE 32
-
-#define CPIO_HEADER_FILESIZE 54
-#define CPIO_HEADER_NAMESIZE 94
-#define CPIO_HEADER_SIZE 110
-
-// Converts the given string 'str' of 'n' length to an integer by assuming it's
-// in base 16.
-__kernel uint64_t strtoul16(const char *str, size_t n)
-{
- char c;
- uint64_t ret = 0;
- uint64_t aux = 0;
-
- for (uint64_t i = 1; n > 0; i *= 16, n--) {
- c = str[n - 1];
- if (c >= 'A' && c <= 'F') {
- aux = 10 + (uint64_t)(c - 'A');
- } else if (c >= 'a' && c <= 'f') {
- aux = 10 + (uint64_t)(c - 'a');
- } else if (c < '0' || c > '9') {
- die("Bad number\n");
- } else {
- aux = (uint64_t)c - '0';
- }
-
- ret += aux * i;
- }
- return ret;
-}
-
-// Returns the 'enum taks_id' that can be gathered by the given path.
-__kernel int get_task_id_from_path(const char *const path)
-{
- if (strcmp(path, "usr/bin/init") == 0) {
- return TASK_INIT;
- } else if (strcmp(path, "usr/bin/fizz") == 0) {
- return TASK_FIZZ;
- } else if (strcmp(path, "usr/bin/buzz") == 0) {
- return TASK_BUZZ;
- } else if (strcmp(path, "usr/bin/fizzbuzz") == 0) {
- return TASK_FIZZBUZZ;
- }
- return TASK_UNKNOWN;
-}
-
-// Fetch the 'entry_addr' for the ELF binary pointed by 'addr'. If everything
-// goes right, the task identified by 'task_id' will finally be initialized with
-// said address.
-__kernel const void *get_task_entry_addr(const unsigned char *const addr)
-{
- uint64_t offset;
-
- 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");
- }
-
- offset = (uint64_t)addr[0x18];
- return (const void *)(addr + offset);
-}
-
-__kernel void extract_initrd(const unsigned char *const initrd_addr, uint64_t size,
- struct task_struct g_tasks[4])
-{
- char buffer[BUFFER_SIZE];
- uint64_t name_size, file_size, padding, base = 0;
- int task_id;
-
- // The `base` is the index from `initrd_addr` which points to the first byte
- // of the header of the currently evaluated file inside of the CPIO archive.
- while (base < size) {
- // Only the "newc" format is supported, without checksums nor fancy
- // stuff.
- if (memcmp(&initrd_addr[base], "070701", 6) != 0) {
- if (memcmp(&initrd_addr[base], "070702", 6) == 0 ||
- memcmp(&initrd_addr[base], "070707", 6) == 0) {
- die("Incorrect cpio format: stick to 'newc'");
- } else {
- die("No cpio magic number");
- }
- }
-
- // We identify the task being extracted by looking at the file's path,
- // so let's first get the size of it.
- memcpy(buffer, &initrd_addr[base + CPIO_HEADER_NAMESIZE], 8);
- buffer[8] = '\0';
- name_size = strtoul16(buffer, 8);
- if (name_size >= BUFFER_SIZE) {
- die("Path too large for initrd executable");
- }
-
- // Right after the header (hence current header + its size) there is the
- // actual file's path, which is exactly `name_size` long. Fetch it now
- // to identify the task at hand.
- memcpy(buffer, &initrd_addr[base + CPIO_HEADER_SIZE], name_size);
- buffer[name_size] = '\0';
- task_id = get_task_id_from_path(buffer);
-
- // Note that this is not necessarily a bad CPIO archive, it might just
- // be the end "TRAILER!!!" delimiter. Either way, just quit at this
- // point.
- if (task_id == TASK_UNKNOWN) {
- break;
- }
-
- // Fetch the size of the executable, which is needed for `extract_elf`,
- // as well as for advancing the `base` to the next file.
- memcpy(buffer, &initrd_addr[base + CPIO_HEADER_FILESIZE], 8);
- buffer[8] = '\0';
- file_size = strtoul16(buffer, 8);
-
- // Files are aligned in 4-byte boundaries after the header. That's why
- // there might be some padding in between the header and the file.
- padding = 4 - ((CPIO_HEADER_SIZE + name_size) & 3);
-
- // And extract the entry address for the current task from the ELF
- // binary.
- g_tasks[task_id].entry_addr =
- get_task_entry_addr(&initrd_addr[base + name_size + CPIO_HEADER_SIZE + padding]);
-
- // Advance the base to the next file.
- base += CPIO_HEADER_SIZE + name_size + padding + file_size;
- }
-}