From 66bee86a8b339cd231f9e44dd3c0cce1ca166842 Mon Sep 17 00:00:00 2001 From: apio Date: Sat, 1 Oct 2022 12:28:32 +0200 Subject: [PATCH] Scheduler: add a load_user_task function that directly loads a file from the initrd --- kernel/include/thread/Scheduler.h | 2 ++ kernel/src/main.cpp | 8 +------ kernel/src/thread/Scheduler.cpp | 35 +++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 7 deletions(-) diff --git a/kernel/include/thread/Scheduler.h b/kernel/include/thread/Scheduler.h index 6359dabe..e6b81a28 100644 --- a/kernel/include/thread/Scheduler.h +++ b/kernel/include/thread/Scheduler.h @@ -10,6 +10,8 @@ namespace Scheduler void add_kernel_task(void (*task)(void)); void add_user_task(void* task); + void load_user_task(const char* filename); + void task_exit(Context* context); void task_misbehave(Context* context); diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index d804e8d8..38927971 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -126,13 +126,7 @@ extern "C" void _start() } }); - void* elf_start_address = ELFLoader::load_elf_from_initrd("bin/init"); - if (!elf_start_address) kerrorln("failed to load /bin/init from initrd"); - else - { - kinfoln("loaded /bin/init at %lx", (uint64_t)elf_start_address); - Scheduler::add_user_task(elf_start_address); - } + Scheduler::load_user_task("bin/init"); kinfoln("Prepared scheduler tasks"); diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index 2c5801dc..f7e3b71f 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -10,6 +10,7 @@ #include "panic/Panic.h" #include "std/stdlib.h" #include "std/string.h" +#include "sys/elf/ELFLoader.h" #include "thread/PIT.h" #include "thread/Task.h" @@ -110,6 +111,40 @@ void Scheduler::add_user_task(void* task) new_task->id, new_task->regs.rsp, task_num); } +void Scheduler::load_user_task(const char* filename) +{ + kinfoln("Loading user task: %s", filename); + Task* new_task = new Task; + ASSERT(new_task); + new_task->id = free_tid++; + new_task->regs.rip = (uint64_t)ELFLoader::load_elf_from_initrd(filename); + if (!new_task->regs.rip) + { + kwarnln("Failed to load user task %s", filename); + delete new_task; + return; + } + new_task->allocated_stack = (uint64_t)MemoryManager::get_pages( + TASK_PAGES_IN_STACK, MAP_READ_WRITE | MAP_USER); // 16 KB is enough for everyone, right? + new_task->regs.rsp = new_task->allocated_stack + (4096 * 4) - sizeof(uintptr_t); + new_task->regs.cs = 0x18 | 0x03; + new_task->regs.ss = 0x20 | 0x03; + new_task->regs.ds = 0x20 | 0x03; + new_task->regs.rflags = (1 << 21) | (1 << 9); // enable interrupts + new_task->task_sleep = 0; + new_task->task_time = 0; + new_task->cpu_time = 0; + end_task->next_task = new_task; + new_task->prev_task = end_task; + base_task->prev_task = new_task; + new_task->next_task = base_task; + end_task = new_task; + new_task->state = new_task->Running; + task_num++; + kinfoln("Adding user task: loaded at %lx, tid %ld, stack at %lx, total tasks: %ld", new_task->regs.rip, + new_task->id, new_task->regs.rsp, task_num); +} + void Scheduler::reap_task(Task* task) { ASSERT(!Interrupts::is_in_handler());