diff --git a/kernel/src/arch/CPU.h b/kernel/src/arch/CPU.h index 54422463..3e56d105 100644 --- a/kernel/src/arch/CPU.h +++ b/kernel/src/arch/CPU.h @@ -26,5 +26,7 @@ namespace CPU void get_stack_trace_at(Registers* regs, void (*callback)(u64, void*), void* arg); void print_stack_trace_at(Registers* regs); + [[noreturn]] void bootstrap_switch_stack(u64 stack, void* function); + void pause(); } diff --git a/kernel/src/arch/x86_64/CPU.cpp b/kernel/src/arch/x86_64/CPU.cpp index 5a56a7c8..b703071c 100644 --- a/kernel/src/arch/x86_64/CPU.cpp +++ b/kernel/src/arch/x86_64/CPU.cpp @@ -295,6 +295,15 @@ namespace CPU &frame_index); } + [[noreturn]] void bootstrap_switch_stack(u64 stack, void* function) + { + asm volatile("mov %0, %%rsp\n" + "jmp *%1" + : + : "r"(stack), "r"(function)); + __builtin_unreachable(); + } + void pause() { asm volatile("pause"); diff --git a/kernel/src/main.cpp b/kernel/src/main.cpp index aad0a78d..2b3e3ffc 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -90,11 +90,19 @@ Result init() return {}; } -extern "C" [[noreturn]] void _start() +[[noreturn]] void init_wrapper() { - Init::check_magic(); - Init::early_init(); auto rc = init(); if (rc.has_error()) kerrorln("Runtime error: %s", rc.error_string()); CPU::idle_loop(); } + +// FIXME: Add a guard page to make sure the stack doesn't end up in random kernel memory. Also reclaim this memory after +// leaving the init task. +extern "C" [[noreturn]] void _start() +{ + Init::check_magic(); + Init::early_init(); + Stack stack { MemoryManager::alloc_for_kernel(8, MMU::ReadWrite | MMU::NoExecute).value(), 8 * ARCH_PAGE_SIZE }; + CPU::bootstrap_switch_stack(stack.top(), (void*)init_wrapper); +}