diff --git a/kernel/src/arch/CPU.h b/kernel/src/arch/CPU.h index ecb0bc17..1c127472 100644 --- a/kernel/src/arch/CPU.h +++ b/kernel/src/arch/CPU.h @@ -28,7 +28,5 @@ namespace CPU u16 get_processor_id(); - [[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 f9feb7e6..101b3c54 100644 --- a/kernel/src/arch/x86_64/CPU.cpp +++ b/kernel/src/arch/x86_64/CPU.cpp @@ -322,15 +322,6 @@ 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 1e10fd4e..97962402 100644 --- a/kernel/src/main.cpp +++ b/kernel/src/main.cpp @@ -45,22 +45,17 @@ Result init() kinfoln("Current platform: %s", CPU::platform_string()); kinfoln("Current processor: %s", CPU::identify().value_or("(unknown)")); - Timer::init(); - kinfoln("Total memory: %s", to_dynamic_unit(MemoryManager::total()).release_value().chars()); kinfoln("Free memory: %s", to_dynamic_unit(MemoryManager::free()).release_value().chars()); kinfoln("Used memory: %s", to_dynamic_unit(MemoryManager::used()).release_value().chars()); kinfoln("Reserved memory: %s", to_dynamic_unit(MemoryManager::reserved()).release_value().chars()); - Thread::init(); - Scheduler::init(); - VFS::root_fs = TRY(TmpFS::FileSystem::create()); TRY(DeviceRegistry::init()); InitRD::populate_vfs(); auto init = TRY(VFS::resolve_path("/bin/init", Credentials {})); - TRY(Scheduler::new_userspace_thread(init, "/bin/init")); + auto init_thread = TRY(Scheduler::new_userspace_thread(init, "/bin/init")); Scheduler::new_kernel_thread(reap_thread, "[reap]").release_value(); @@ -71,43 +66,36 @@ Result init() }, { .klass = 1 }); - CPU::platform_finish_init(); - // Disable console logging before transferring control to userspace. setup_log(log_debug_enabled(), log_serial_enabled(), false); - CPU::enable_interrupts(); + init_thread->state = ThreadState::Runnable; - return {}; + kernel_exit(); } [[noreturn]] void init_wrapper() { auto rc = init(); if (rc.has_error()) kerrorln("Runtime error: %s", rc.error_string()); - CPU::idle_loop(); -} - -static constexpr u64 BOOTSTRAP_STACK_PAGES = 8; - -// FIXME: Reclaim this memory as soon as we leave the init task (so as soon as the Scheduler runs a task switch) -static u64 allocate_initial_kernel_stack() -{ - u64 address = MemoryManager::alloc_for_kernel(BOOTSTRAP_STACK_PAGES + 1, MMU::ReadWrite | MMU::NoExecute).value(); - // First page is a guard page, the rest is stack. - MMU::unmap(address); // Unmap (without deallocating VM) one guard page so that attempts to access it fail with a - // non-present page fault. - - // The actual stack. - Stack stack { address + ARCH_PAGE_SIZE, BOOTSTRAP_STACK_PAGES * ARCH_PAGE_SIZE }; - - return stack.top(); + kernel_exit(); } extern "C" [[noreturn]] void _start() { Init::check_magic(); Init::early_init(); - u64 bootstrap_stack_top = allocate_initial_kernel_stack(); - CPU::bootstrap_switch_stack(bootstrap_stack_top, (void*)init_wrapper); + + Timer::init(); + + Thread::init(); + Scheduler::init(); + + Scheduler::new_kernel_thread(init_wrapper, "[kinit]"); + + CPU::platform_finish_init(); + + CPU::enable_interrupts(); + + CPU::idle_loop(); } diff --git a/kernel/src/thread/Scheduler.cpp b/kernel/src/thread/Scheduler.cpp index 50a5d70a..cd40975c 100644 --- a/kernel/src/thread/Scheduler.cpp +++ b/kernel/src/thread/Scheduler.cpp @@ -76,6 +76,8 @@ namespace Scheduler g_threads.append(thread); + thread->state = ThreadState::Runnable; + kinfoln("Created kernel thread: id %lu with ip %#lx and sp %#lx", thread->id, thread->ip(), thread->sp()); return {}; @@ -109,11 +111,13 @@ namespace Scheduler return new_kernel_thread_impl(thread, name); } - Result new_userspace_thread(SharedPtr inode, const char* name) + Result new_userspace_thread(SharedPtr inode, const char* name) { - Thread* const thread = TRY(new_thread()); + Thread* const thread = TRY(make()); + thread->state = ThreadState::None; thread->is_kernel = false; + thread->id = 1; thread->name = name; thread->parent_id = 0; thread->auth = Credentials { .uid = 0, .euid = 0, .suid = 0, .gid = 0, .egid = 0, .sgid = 0 }; @@ -140,7 +144,7 @@ namespace Scheduler g_threads.append(thread); - return {}; + return thread; } void add_thread(Thread* thread) diff --git a/kernel/src/thread/Scheduler.h b/kernel/src/thread/Scheduler.h index f0ced1d1..9f36479d 100644 --- a/kernel/src/thread/Scheduler.h +++ b/kernel/src/thread/Scheduler.h @@ -13,7 +13,7 @@ namespace Scheduler Result new_kernel_thread(void (*func)(void), const char* name); Result new_kernel_thread(void (*func)(void*), void* arg, const char* name); - Result new_userspace_thread(SharedPtr inode, const char* name); + Result new_userspace_thread(SharedPtr inode, const char* name); void add_thread(Thread* thread); diff --git a/kernel/src/thread/Thread.cpp b/kernel/src/thread/Thread.cpp index 6b6ed296..4a45ebde 100644 --- a/kernel/src/thread/Thread.cpp +++ b/kernel/src/thread/Thread.cpp @@ -12,7 +12,7 @@ LinkedList g_threads; void Thread::init() { - g_next_id = 1; + g_next_id = 2; } Result new_thread() diff --git a/kernel/src/thread/Thread.h b/kernel/src/thread/Thread.h index 8ddbff2e..5257d5f0 100644 --- a/kernel/src/thread/Thread.h +++ b/kernel/src/thread/Thread.h @@ -18,6 +18,7 @@ enum class ThreadState { + None, Idle, Runnable, Sleeping,