diff options
Diffstat (limited to 'src/initrd.c')
-rw-r--r-- | src/initrd.c | 112 |
1 files changed, 28 insertions, 84 deletions
diff --git a/src/initrd.c b/src/initrd.c index b8e8d09..1534210 100644 --- a/src/initrd.c +++ b/src/initrd.c @@ -1,9 +1,6 @@ /** * @file initrd.c * Initrd image support - * An archive file (made with ar) can be linked into the final executable to - * allow files to be loaded in memory on boot. See mkinitrd.sh or the Makefile - * for more info. * * Copyright (C) 2018 Clyne Sullivan * @@ -21,110 +18,57 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ +/** + * The format of the initrd file is custom; made with the 'rba' utility. + */ + #include <initrd.h> +#include <string.h> extern uint8_t _binary_initrd_img_start[]; extern uint8_t _binary_initrd_img_size[]; -static const void *initrd_start = (void *)_binary_initrd_img_start; +static const uint8_t *initrd_start = (uint8_t *)_binary_initrd_img_start; static const uint32_t initrd_size = (uint32_t)_binary_initrd_img_size; -static const char *initrd_sig = "!<arch>\n"; - uint8_t initrd_validate(void) { - initrd_header *header = (initrd_header *)initrd_start; - for (uint8_t i = 0; i < 8; i++) { - if (header->signature[i] != initrd_sig[i]) - return 0; - } - - return 1; + return 1; // TODO maybe add header/signature to archiver? } -uint8_t initrd_nametest(char *file, const char *want) +char *initrd_getfile(uint32_t offset) { - for (uint8_t i = 0; i < 16; i++) { - if (want[i] == '\0') - return (file[i] == '/'); - else if (want[i] != file[i]) + char *ptr = initrd_start; + for (uint32_t i = 0; i < offset; i++) { + uint32_t len = *((uint32_t *)ptr); + uint32_t datalen = *((uint32_t *)(ptr + 4 + len)); + ptr += len + datalen + 8; + if (ptr >= (char *)(initrd_start + initrd_size)) return 0; } - return 0; -} - -uint32_t ipow10(uint8_t n) -{ - uint32_t i = 1; - while (n--) - i *= 10; - return i; -} - -uint32_t initrd_getsize(initrd_file *file) -{ - uint32_t size = 0; - char *p = file->size + 10; - while (*--p == ' '); - - for (int8_t i = p - file->size, j = 0; i >= 0; i--, j++) - size += (*p-- - '0') * ipow10(j); - - return size; + return ptr; } -initrd_file *initrd_getfileptr(const char *name) +char *initrd_readfile(const char *name) { - initrd_file *file = (initrd_file *)((uint8_t *)initrd_start + sizeof(initrd_header)); - uint32_t offset = sizeof(initrd_header); - - while (offset < initrd_size) { - if (initrd_nametest(file->name, name)) - return file; - uint32_t size = initrd_getsize(file) + sizeof(initrd_file); - offset += size; - file = (initrd_file *)((uint8_t *)file + size + 1); + char *ptr; + for (uint32_t i = 0; ptr = initrd_getfile(i), ptr != 0; i++) { + uint32_t len = *((uint32_t *)ptr); + if (!strncmp(name, ptr + 4, len)) + return ptr + len + 8; } - return 0; } -char *initrd_getnfile(unsigned int index) +uint32_t initrd_filesize(const char *name) { - initrd_file *file = (initrd_file *)((uint8_t *)initrd_start + sizeof(initrd_header)); - uint32_t offset = sizeof(initrd_header); - - for (unsigned int i = 0; i < index; i++) { - uint32_t size = initrd_getsize(file) + sizeof(initrd_file); - offset += size; - file = (initrd_file *)((uint8_t *)file + size); - if (file->name[0] == '\n') - file = (initrd_file *)((uint32_t)file + 1); + char *ptr; + for (uint32_t i = 0; ptr = initrd_getfile(i), ptr != 0; i++) { + uint32_t len = *((uint32_t *)ptr); + if (!strncmp(name, ptr + 4, len)) + return *((uint32_t *)(ptr + len + 4)); } - if ((uint32_t)file >= (uint32_t)initrd_start + initrd_size) - return 0; - return file->name; -} - -char *initrd_getfile(const char *name) -{ - initrd_file *file = initrd_getfileptr(name); - if (file == 0) - return 0; - - - char *ptr = (char *)file + sizeof(initrd_file); - ptr[initrd_getsize(file) - 1] = 0; - return ptr; -} - -uint32_t initrd_getfilesize(const char *name) -{ - initrd_file *file = initrd_getfileptr(name); - if (file == 0) - return 0; - - return initrd_getsize(file); + return 0; } |