From 0131193379b86327f63a3dc28fcbf48b3f210041 Mon Sep 17 00:00:00 2001 From: apio Date: Tue, 11 Oct 2022 19:33:48 +0200 Subject: [PATCH] ELFLoader, Scheduler: Transition to use VFS We should start to drop the old InitRD API, which only allows for files to be loaded from the initrd, and which forces pathnames to be relative (bin/init) With VFS, we can load any kind of file from any kind of filesystem, and using paths that make sense (/bin/init) --- kernel/include/sys/elf/ELFLoader.h | 2 +- kernel/src/main.cpp | 48 +----------------------------- kernel/src/sys/elf/ELFLoader.cpp | 30 ++++++++++++++++--- kernel/src/thread/Scheduler.cpp | 2 +- 4 files changed, 29 insertions(+), 53 deletions(-) diff --git a/kernel/include/sys/elf/ELFLoader.h b/kernel/include/sys/elf/ELFLoader.h index b7c1de9f..1cdc8fd9 100644 --- a/kernel/include/sys/elf/ELFLoader.h +++ b/kernel/include/sys/elf/ELFLoader.h @@ -5,5 +5,5 @@ namespace ELFLoader { ELFImage* load_elf_from_address(uintptr_t addr); - ELFImage* load_elf_from_initrd(const char* filename); + ELFImage* load_elf_from_filesystem(const char* filename); } \ No newline at end of file diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index 93f7231e..338f0933 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -70,52 +70,6 @@ extern "C" void _start() kinfoln("Prepared scheduler"); - /*Scheduler::add_kernel_task([]() { - int64_t x = 0; - int64_t y = 0; - int64_t xvel = 10; - int64_t yvel = 10; - while (1) - { - sleep(2); - uint32_t color = (uint32_t)Mersenne::get(); - x += xvel; - y += yvel; - if ((x + 10) >= framebuffer0.width()) - { - xvel = -xvel; - x = (framebuffer0.width() - 10); - } - if ((y + 10) >= framebuffer0.height()) - { - yvel = -yvel; - y = (framebuffer0.height() - 10); - } - if (xvel < 0 && (x - 10) < 0) - { - xvel = -xvel; - x = 0; - } - if (yvel < 0 && (y - 10) < 0) - { - yvel = -yvel; - y = 0; - } - framebuffer0.paint_rect(x, y, 10, 10, Color::from_integer(color)); - } - });*/ - - /*Scheduler::add_kernel_task([]() { - while (1) - { - sleep(100); - uint32_t color = (uint32_t)Mersenne::get(); - framebuffer0.paint_rect(Mersenne::get() % (framebuffer0.width() - 256), - Mersenne::get() % (framebuffer0.height() - 256), Mersenne::get() % 255, - Mersenne::get() % 255, Color::from_integer(color)); - } - });*/ - Scheduler::add_kernel_task([]() { while (1) { @@ -124,7 +78,7 @@ extern "C" void _start() } }); - Scheduler::load_user_task("bin/init"); + Scheduler::load_user_task("/bin/init"); kinfoln("Prepared scheduler tasks"); diff --git a/kernel/src/sys/elf/ELFLoader.cpp b/kernel/src/sys/elf/ELFLoader.cpp index f4690177..70f8225d 100644 --- a/kernel/src/sys/elf/ELFLoader.cpp +++ b/kernel/src/sys/elf/ELFLoader.cpp @@ -1,6 +1,7 @@ #define MODULE "elf" #include "sys/elf/ELFLoader.h" +#include "fs/VFS.h" #include "init/InitRD.h" #include "log/Log.h" #include "memory/MemoryManager.h" @@ -19,16 +20,37 @@ static const char* format_permissions(uint32_t flags) return perms; } -ELFImage* ELFLoader::load_elf_from_initrd(const char* filename) +ELFImage* ELFLoader::load_elf_from_filesystem(const char* filename) { - InitRD::File elf_file = InitRD::open(filename); - if (!elf_file.addr) + VFS::Node* node = VFS::resolve_path(filename); + + if (!node) { kwarnln("Failed to open file %s for loading", filename); return 0; } - return load_elf_from_address((uintptr_t)elf_file.addr); + if (node->type == VFS_DIRECTORY) + { + kwarnln("Failed to load %s: is a directory", filename); + return 0; + } + + void* file = kmalloc(node->length); + if (VFS::read(node, 0, node->length, (char*)file) < 0) + { + kwarnln("Failed to read ELF image from file"); + kfree(file); + return 0; + } + + ELFImage* result = + load_elf_from_address((uintptr_t)file); // FIXME: Read headers and sections as we go along the file, to avoid + // loading the entire file at once into memory. + + kfree(file); + + return result; } ELFImage* ELFLoader::load_elf_from_address(uintptr_t addr) diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index 62b090ef..71856ade 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -117,7 +117,7 @@ void Scheduler::load_user_task(const char* filename) Task* new_task = new Task; ASSERT(new_task); new_task->id = free_tid++; - ELFImage* image = ELFLoader::load_elf_from_initrd(filename); + ELFImage* image = ELFLoader::load_elf_from_filesystem(filename); if (!image) { kerrorln("Failed to load %s from initrd", filename);