summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordzwdz2022-07-23 19:28:43 +0200
committerdzwdz2022-07-23 19:28:43 +0200
commit20c7b5be3bbb5f56a31536c018e20706100f57ae (patch)
tree47dde902a7d2a2ff464c600d76b4743fe8153e63
parent3badc5ac30fcc0836a2604146788158b16b64f2d (diff)
user_bootstrap: pass the initrd in an argument to init's main
-rw-r--r--src/user/app/main.c9
-rw-r--r--src/user/lib/elfload.c51
-rw-r--r--src/user/lib/elfload.h1
-rw-r--r--src/user_bootstrap/main.c12
4 files changed, 48 insertions, 25 deletions
diff --git a/src/user/app/main.c b/src/user/app/main.c
index 28c4aa0..9f4d50c 100644
--- a/src/user/app/main.c
+++ b/src/user/app/main.c
@@ -9,16 +9,17 @@
#include <user/lib/stdlib.h>
#include <user/tests/main.h>
-// extern char _initrd;
+__attribute__((visibility("hidden")))
+extern char _image_base[];
void read_file(const char *path, size_t len);
__attribute__((section(".text.startup")))
-int main(void) {
+int main(void *initrd) {
elf_selfreloc();
file_reopen(stdout, "/com1", 0);
- printf("preinit\n");
+ printf("in init, loaded at 0x%x\n", &_image_base);
/* move everything provided by the kernel to /kdev */
MOUNT("/kdev/", fs_passthru(NULL));
@@ -28,7 +29,7 @@ int main(void) {
}
if (!fork2_n_mount("/")) fs_dir_inject("/kdev/"); // TODO should be part of fs_whitelist
- // MOUNT("/init/", tar_driver(&_initrd));
+ MOUNT("/init/", tar_driver(initrd));
MOUNT("/tmp/", tmpfs_drv());
MOUNT("/keyboard", ps2_drv());
MOUNT("/vga_tty", ansiterm_drv());
diff --git a/src/user/lib/elfload.c b/src/user/lib/elfload.c
index 6c75268..ef14388 100644
--- a/src/user/lib/elfload.c
+++ b/src/user/lib/elfload.c
@@ -62,41 +62,58 @@ static size_t elf_spread(const void *elf) {
return high - low;
}
-/* frees memory outside of [low; high] and jumps to *entry */
-static void freejmp(void *entry, void *low, void *high) {
+/* frees memory outside of [low; low + len] and jumps to *entry */
+static void freejmp(void *entry, void *low, size_t len) {
+ uintptr_t high = (uintptr_t)low + len;
uint64_t buf[] = {
EXECBUF_SYSCALL, _SYSCALL_MEMFLAG, 0, (uintptr_t)low, 0, 0,
- EXECBUF_SYSCALL, _SYSCALL_MEMFLAG, (uintptr_t)high, ~0 - 0xF000 - (uintptr_t)high, 0, 0,
+ EXECBUF_SYSCALL, _SYSCALL_MEMFLAG, high, ~0 - 0xF000 - high, 0, 0,
EXECBUF_JMP, (uintptr_t)entry,
};
_syscall_execbuf(buf, sizeof buf);
+ // should never return
}
-void elf_exec(void *base) {
- struct Elf64_Ehdr *ehdr = base;
+static void *elf_loadmem(struct Elf64_Ehdr *ehdr) {
void *exebase;
- if (!valid_ehdr(ehdr)) return;
- _syscall_debug_klog("here", 4);
- size_t spread = elf_spread(base);
+ size_t spread = elf_spread(ehdr);
switch (ehdr->e_type) {
case ET_EXEC:
exebase = (void*)0;
break;
case ET_DYN:
exebase = _syscall_memflag((void*)0x1000, spread, MEMFLAG_FINDFREE);
- if (!exebase) {
- printf("elf: out of memory\n");
- _syscall_exit(1);
- }
+ if (!exebase)
+ return NULL;
break;
default:
- return;
+ return NULL;
}
for (size_t phi = 0; phi < ehdr->e_phnum; phi++) {
- if (!load_phdr(base, exebase, phi))
- return;
+ if (!load_phdr((void*)ehdr, exebase, phi)) {
+ _syscall_memflag(exebase, spread, 0);
+ return NULL;
+ }
}
+ return exebase;
+}
+
+void elf_exec(void *base) {
+ struct Elf64_Ehdr *ehdr = base;
+ if (!valid_ehdr(ehdr)) return;
+
+ void *exebase = elf_loadmem(ehdr);
+ if (!exebase) return;
+
+ freejmp(exebase + ehdr->e_entry, exebase, elf_spread(ehdr) + 0x1000);
+}
+
+void *elf_partialexec(void *base) {
+ struct Elf64_Ehdr *ehdr = base;
+ if (!valid_ehdr(ehdr)) return NULL;
+
+ void *exebase = elf_loadmem(ehdr);
+ if (!exebase) return NULL;
- freejmp(exebase + ehdr->e_entry, exebase, exebase + spread + 0x1000);
- printf("elf: execbuf failed?");
+ return exebase + ehdr->e_entry;
}
diff --git a/src/user/lib/elfload.h b/src/user/lib/elfload.h
index f79be6e..40c4874 100644
--- a/src/user/lib/elfload.h
+++ b/src/user/lib/elfload.h
@@ -3,5 +3,6 @@
void elf_execf(libc_file *f);
void elf_exec(void *elf);
+void *elf_partialexec(void *elf); /* returns pointer to entry point */
void elf_selfreloc(void); // elfreloc.c
diff --git a/src/user_bootstrap/main.c b/src/user_bootstrap/main.c
index 71647c4..52d7058 100644
--- a/src/user_bootstrap/main.c
+++ b/src/user_bootstrap/main.c
@@ -10,7 +10,7 @@ extern char _initrd;
/* libc stubs */
int printf(const char *fmt, ...) {(void)fmt; return 0;}
void *malloc(size_t size) {(void)size; _syscall_exit(1);}
-void free(void *ptr) {}
+void free(void *ptr) {(void)ptr;}
int file_read(libc_file *f, char *buf, size_t len) {(void)f; (void)buf; (void)len; _syscall_exit(1);}
@@ -52,8 +52,12 @@ int main(void) {
_syscall_memflag(&_bss_start, &_bss_end - &_bss_start, MEMFLAG_PRESENT);
void *init = tar_find(&_initrd, "init.elf");
- elf_exec(init);
- _syscall_debug_klog("bootstrap failed", sizeof("bootstrap failed"));
-
+ void (*entry)(void*) = elf_partialexec(init);
+ if (entry) {
+ // TODO dynamically link initrd
+ entry(&_initrd);
+ } else {
+ _syscall_debug_klog("bootstrap failed", sizeof("bootstrap failed"));
+ }
_syscall_exit(0);
}