From 90af8825a41981ce2ee52e0a9ce84f624eb022e6 Mon Sep 17 00:00:00 2001 From: dzwdz Date: Tue, 26 Jul 2022 00:38:45 +0200 Subject: move user_bootstrap to user/bootstrap for consistency's sake --- Makefile | 4 +- src/user/bootstrap/linker.ld | 37 ++++++++++ src/user/bootstrap/main.c | 36 ++++++++++ src/user/bootstrap/tar.c | 159 +++++++++++++++++++++++++++++++++++++++++++ src/user/bootstrap/tar.h | 5 ++ src/user_bootstrap/linker.ld | 37 ---------- src/user_bootstrap/main.c | 36 ---------- src/user_bootstrap/tar.c | 159 ------------------------------------------- src/user_bootstrap/tar.h | 5 -- 9 files changed, 239 insertions(+), 239 deletions(-) create mode 100644 src/user/bootstrap/linker.ld create mode 100644 src/user/bootstrap/main.c create mode 100644 src/user/bootstrap/tar.c create mode 100644 src/user/bootstrap/tar.h delete mode 100644 src/user_bootstrap/linker.ld delete mode 100644 src/user_bootstrap/main.c delete mode 100644 src/user_bootstrap/tar.c delete mode 100644 src/user_bootstrap/tar.h diff --git a/Makefile b/Makefile index 08613e8..0b57534 100644 --- a/Makefile +++ b/Makefile @@ -60,7 +60,7 @@ out/fs/boot/kernel.bin: src/kernel/linker.ld $(call from_sources, src/kernel/) $ @$(CC) $(LFLAGS) -T $^ -o $@ grub-file --is-x86-multiboot $@ -out/bootstrap: src/user_bootstrap/linker.ld $(call from_sources, src/user_bootstrap/) $(call from_sources, src/user/lib/) $(call from_sources, src/shared/) +out/bootstrap: src/user/bootstrap/linker.ld $(call from_sources, src/user/bootstrap/) $(call from_sources, src/user/lib/) $(call from_sources, src/shared/) @mkdir -p $(@D) @$(CC) $(LFLAGS) -T $^ -o $@ @@ -101,7 +101,7 @@ out/obj/%.c.o: src/%.c @mkdir -p $(@D) @$(CC) $(CFLAGS) -fPIC -c $^ -o $@ -out/obj/user_bootstrap/%.c.o: src/user_bootstrap/%.c +out/obj/user/bootstrap/%.c.o: src/user/bootstrap/%.c @mkdir -p $(@D) @$(CC) $(CFLAGS) -c $^ -o $@ diff --git a/src/user/bootstrap/linker.ld b/src/user/bootstrap/linker.ld new file mode 100644 index 0000000..917388c --- /dev/null +++ b/src/user/bootstrap/linker.ld @@ -0,0 +1,37 @@ +ENTRY(main) +OUTPUT_FORMAT("binary") + +SECTIONS +{ + /* Not an ELF, but we need this to link with elfreloc.c. + * Not that we need to link with it, it's just easier that way */ + _DYNAMIC = 0; + _image_base = 0; + + . = 2M; + .text BLOCK(4K) : ALIGN(4K) + { + *(.text.startup) + *(.text) + } + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + + . = ALIGN(32); /* seems to be necessary? */ + _initrd = .; /* is just appended onto the end of the binary */ + . += 2M; + + _bss_start = .; + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + } + _bss_end = .; +} diff --git a/src/user/bootstrap/main.c b/src/user/bootstrap/main.c new file mode 100644 index 0000000..5f36aa1 --- /dev/null +++ b/src/user/bootstrap/main.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include +#include + +#include "tar.h" + +extern char _bss_start; +extern char _bss_end; +extern char _initrd; + +__attribute__((section(".text.startup"))) +int main(void) { + _syscall_memflag(&_bss_start, &_bss_end - &_bss_start, MEMFLAG_PRESENT); + + /* move everything provided by the kernel to /kdev */ + MOUNT("/kdev/", fs_passthru(NULL)); + if (!fork2_n_mount("/")) { + const char *l[] = {"/kdev/", NULL}; + fs_whitelist(l); + } + if (!fork2_n_mount("/")) fs_dir_inject("/kdev/"); // TODO should be part of fs_whitelist + + MOUNT("/init/", tar_driver(&_initrd)); + + void *init = tar_find("init.elf", 8, &_initrd, ~0) + 512; + if (init) { + _klogf("execing init.elf"); + elf_exec(init); + _klogf("elf_exec failed"); + } else { + _klogf("couldn't find init.elf"); + } + _syscall_exit(1); +} diff --git a/src/user/bootstrap/tar.c b/src/user/bootstrap/tar.c new file mode 100644 index 0000000..40da437 --- /dev/null +++ b/src/user/bootstrap/tar.c @@ -0,0 +1,159 @@ +#include +#include +#include +#include + +#include "tar.h" + +#define BUF_SIZE 64 + +static void *tar_open(const char *path, int len, void *base, size_t base_len); +static void tar_read(struct fs_wait_response *res, void *base, size_t base_len); +static int tar_size(void *sector); +static int oct_parse(char *str, size_t len); + + +static const char *root_fakemeta = ""; /* see comment in tar_open */ + + +void tar_driver(void *base) { + static char buf[BUF_SIZE]; + struct fs_wait_response res; + void *ptr; + while (!_syscall_fs_wait(buf, BUF_SIZE, &res)) { + switch (res.op) { + case VFSOP_OPEN: + ptr = tar_open(buf, res.len, base, ~0); + _syscall_fs_respond(ptr, ptr ? 0 : -1, 0); + break; + + case VFSOP_READ: + tar_read(&res, base, ~0); + break; + + default: + _syscall_fs_respond(NULL, -1, 0); // unsupported + break; + } + } + _syscall_exit(0); +} + +static void *tar_open(const char *path, int len, void *base, size_t base_len) { + if (len <= 0) return NULL; + path += 1; // skip the leading slash + len -= 1; + + /* TAR archives don't (seem to) contain an entry for the root dir, so i'm + * returning a fake one. this isn't a full entry because i'm currently too + * lazy to create a full one - thus, it has to be special cased in tar_read */ + if (len == 0) + return (void*)root_fakemeta; + + return tar_find(path, len, base, base_len); +} + +static void tar_read(struct fs_wait_response *res, void *base, size_t base_len) { + void *meta = (void*)res->id; + char type = *(char*)(meta + 156); + size_t meta_len; + int size; + + static char buf[BUF_SIZE]; // TODO reuse a single buffer + size_t buf_pos = 0; + + if (meta == root_fakemeta) type = '5'; /* see comment in tar_open() */ + + switch (type) { + case '\0': + case '0': /* normal files */ + size = tar_size(meta); + if (res->offset < 0 || res->offset > size) { + // TODO support negative offsets + _syscall_fs_respond(NULL, -1, 0); + } else { + _syscall_fs_respond(meta + 512 + res->offset, size - res->offset, 0); + } + break; + + case '5': /* directory */ + meta_len = strlen(meta); + size_t to_skip = res->offset; + + /* find files in dir */ + for (size_t off = 0; off < base_len;) { + if (0 != memcmp(base + off + 257, "ustar", 5)) + break; // not a metadata sector + // TODO more meaningful variable names and clean code up + + /* check if prefix matches */ + if (0 == memcmp(base + off, meta, meta_len) && + *(char*)(base + off + meta_len) != '\0') { + char *suffix = base + off + meta_len; + size_t suffix_len = strlen(suffix); + + /* check if the path contains any non-trailing slashes */ + char *next = suffix; + while (*next && *next != '/') next++; + if (*next == '/') next++; + if (*next == '\0') { + if (to_skip > suffix_len) { + to_skip -= suffix_len; + } else { + suffix += to_skip; + suffix_len -= to_skip; + to_skip = 0; + + /* it doesn't - so let's add it to the result */ + memcpy(buf + buf_pos, suffix, suffix_len); + buf[buf_pos + suffix_len] = '\0'; + buf_pos += suffix_len + 1; + // TODO no buffer overrun check + } + } + } + + size = tar_size(base + off); + off += 512; // skip this metadata sector + off += (size + 511) & ~511; // skip the data sectors + } + + _syscall_fs_respond(buf, buf_pos, 0); + break; + + default: + _syscall_fs_respond(NULL, -1, 0); + break; + } +} + +static int tar_size(void *sector) { + return oct_parse(sector + 124, 11); +} + +void *tar_find(const char *path, size_t path_len, void *base, size_t base_len) { + int size; + if (path_len > 100) return NULL; // illegal path + + for (size_t off = 0; off < base_len;) { + if (0 != memcmp(base + off + 257, "ustar", 5)) + break; // not a metadata sector + if (0 == memcmp(base + off, path, path_len) && + *(char*)(base + off + path_len) == '\0') + return base + off; // file found, quit + + size = tar_size(base + off); + off += 512; // skip this metadata sector + off += (size + 511) & ~511; // skip the data sectors + } + return NULL; +} + +static int oct_parse(char *str, size_t len) { + int res = 0; + for (size_t i = 0; i < len; i++) { + res *= 8; + res += str[i] - '0'; // no format checking + } + return res; +} diff --git a/src/user/bootstrap/tar.h b/src/user/bootstrap/tar.h new file mode 100644 index 0000000..43aa9ed --- /dev/null +++ b/src/user/bootstrap/tar.h @@ -0,0 +1,5 @@ +#pragma once +#include + +_Noreturn void tar_driver(void *base); +void *tar_find(const char *path, size_t path_len, void *base, size_t base_len); diff --git a/src/user_bootstrap/linker.ld b/src/user_bootstrap/linker.ld deleted file mode 100644 index 917388c..0000000 --- a/src/user_bootstrap/linker.ld +++ /dev/null @@ -1,37 +0,0 @@ -ENTRY(main) -OUTPUT_FORMAT("binary") - -SECTIONS -{ - /* Not an ELF, but we need this to link with elfreloc.c. - * Not that we need to link with it, it's just easier that way */ - _DYNAMIC = 0; - _image_base = 0; - - . = 2M; - .text BLOCK(4K) : ALIGN(4K) - { - *(.text.startup) - *(.text) - } - .rodata BLOCK(4K) : ALIGN(4K) - { - *(.rodata) - } - .data BLOCK(4K) : ALIGN(4K) - { - *(.data) - } - - . = ALIGN(32); /* seems to be necessary? */ - _initrd = .; /* is just appended onto the end of the binary */ - . += 2M; - - _bss_start = .; - .bss BLOCK(4K) : ALIGN(4K) - { - *(COMMON) - *(.bss) - } - _bss_end = .; -} diff --git a/src/user_bootstrap/main.c b/src/user_bootstrap/main.c deleted file mode 100644 index 5f36aa1..0000000 --- a/src/user_bootstrap/main.c +++ /dev/null @@ -1,36 +0,0 @@ -#include -#include -#include -#include -#include - -#include "tar.h" - -extern char _bss_start; -extern char _bss_end; -extern char _initrd; - -__attribute__((section(".text.startup"))) -int main(void) { - _syscall_memflag(&_bss_start, &_bss_end - &_bss_start, MEMFLAG_PRESENT); - - /* move everything provided by the kernel to /kdev */ - MOUNT("/kdev/", fs_passthru(NULL)); - if (!fork2_n_mount("/")) { - const char *l[] = {"/kdev/", NULL}; - fs_whitelist(l); - } - if (!fork2_n_mount("/")) fs_dir_inject("/kdev/"); // TODO should be part of fs_whitelist - - MOUNT("/init/", tar_driver(&_initrd)); - - void *init = tar_find("init.elf", 8, &_initrd, ~0) + 512; - if (init) { - _klogf("execing init.elf"); - elf_exec(init); - _klogf("elf_exec failed"); - } else { - _klogf("couldn't find init.elf"); - } - _syscall_exit(1); -} diff --git a/src/user_bootstrap/tar.c b/src/user_bootstrap/tar.c deleted file mode 100644 index 40da437..0000000 --- a/src/user_bootstrap/tar.c +++ /dev/null @@ -1,159 +0,0 @@ -#include -#include -#include -#include - -#include "tar.h" - -#define BUF_SIZE 64 - -static void *tar_open(const char *path, int len, void *base, size_t base_len); -static void tar_read(struct fs_wait_response *res, void *base, size_t base_len); -static int tar_size(void *sector); -static int oct_parse(char *str, size_t len); - - -static const char *root_fakemeta = ""; /* see comment in tar_open */ - - -void tar_driver(void *base) { - static char buf[BUF_SIZE]; - struct fs_wait_response res; - void *ptr; - while (!_syscall_fs_wait(buf, BUF_SIZE, &res)) { - switch (res.op) { - case VFSOP_OPEN: - ptr = tar_open(buf, res.len, base, ~0); - _syscall_fs_respond(ptr, ptr ? 0 : -1, 0); - break; - - case VFSOP_READ: - tar_read(&res, base, ~0); - break; - - default: - _syscall_fs_respond(NULL, -1, 0); // unsupported - break; - } - } - _syscall_exit(0); -} - -static void *tar_open(const char *path, int len, void *base, size_t base_len) { - if (len <= 0) return NULL; - path += 1; // skip the leading slash - len -= 1; - - /* TAR archives don't (seem to) contain an entry for the root dir, so i'm - * returning a fake one. this isn't a full entry because i'm currently too - * lazy to create a full one - thus, it has to be special cased in tar_read */ - if (len == 0) - return (void*)root_fakemeta; - - return tar_find(path, len, base, base_len); -} - -static void tar_read(struct fs_wait_response *res, void *base, size_t base_len) { - void *meta = (void*)res->id; - char type = *(char*)(meta + 156); - size_t meta_len; - int size; - - static char buf[BUF_SIZE]; // TODO reuse a single buffer - size_t buf_pos = 0; - - if (meta == root_fakemeta) type = '5'; /* see comment in tar_open() */ - - switch (type) { - case '\0': - case '0': /* normal files */ - size = tar_size(meta); - if (res->offset < 0 || res->offset > size) { - // TODO support negative offsets - _syscall_fs_respond(NULL, -1, 0); - } else { - _syscall_fs_respond(meta + 512 + res->offset, size - res->offset, 0); - } - break; - - case '5': /* directory */ - meta_len = strlen(meta); - size_t to_skip = res->offset; - - /* find files in dir */ - for (size_t off = 0; off < base_len;) { - if (0 != memcmp(base + off + 257, "ustar", 5)) - break; // not a metadata sector - // TODO more meaningful variable names and clean code up - - /* check if prefix matches */ - if (0 == memcmp(base + off, meta, meta_len) && - *(char*)(base + off + meta_len) != '\0') { - char *suffix = base + off + meta_len; - size_t suffix_len = strlen(suffix); - - /* check if the path contains any non-trailing slashes */ - char *next = suffix; - while (*next && *next != '/') next++; - if (*next == '/') next++; - if (*next == '\0') { - if (to_skip > suffix_len) { - to_skip -= suffix_len; - } else { - suffix += to_skip; - suffix_len -= to_skip; - to_skip = 0; - - /* it doesn't - so let's add it to the result */ - memcpy(buf + buf_pos, suffix, suffix_len); - buf[buf_pos + suffix_len] = '\0'; - buf_pos += suffix_len + 1; - // TODO no buffer overrun check - } - } - } - - size = tar_size(base + off); - off += 512; // skip this metadata sector - off += (size + 511) & ~511; // skip the data sectors - } - - _syscall_fs_respond(buf, buf_pos, 0); - break; - - default: - _syscall_fs_respond(NULL, -1, 0); - break; - } -} - -static int tar_size(void *sector) { - return oct_parse(sector + 124, 11); -} - -void *tar_find(const char *path, size_t path_len, void *base, size_t base_len) { - int size; - if (path_len > 100) return NULL; // illegal path - - for (size_t off = 0; off < base_len;) { - if (0 != memcmp(base + off + 257, "ustar", 5)) - break; // not a metadata sector - if (0 == memcmp(base + off, path, path_len) && - *(char*)(base + off + path_len) == '\0') - return base + off; // file found, quit - - size = tar_size(base + off); - off += 512; // skip this metadata sector - off += (size + 511) & ~511; // skip the data sectors - } - return NULL; -} - -static int oct_parse(char *str, size_t len) { - int res = 0; - for (size_t i = 0; i < len; i++) { - res *= 8; - res += str[i] - '0'; // no format checking - } - return res; -} diff --git a/src/user_bootstrap/tar.h b/src/user_bootstrap/tar.h deleted file mode 100644 index 43aa9ed..0000000 --- a/src/user_bootstrap/tar.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#include - -_Noreturn void tar_driver(void *base); -void *tar_find(const char *path, size_t path_len, void *base, size_t base_len); -- cgit v1.2.3