kernel: Run the initialization process in a thread
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This way we can give it more stack and also reclaim it later!
This commit is contained in:
parent
b1e400d795
commit
77dcfab5ef
@ -28,7 +28,5 @@ namespace CPU
|
|||||||
|
|
||||||
u16 get_processor_id();
|
u16 get_processor_id();
|
||||||
|
|
||||||
[[noreturn]] void bootstrap_switch_stack(u64 stack, void* function);
|
|
||||||
|
|
||||||
void pause();
|
void pause();
|
||||||
}
|
}
|
||||||
|
@ -322,15 +322,6 @@ namespace CPU
|
|||||||
&frame_index);
|
&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()
|
void pause()
|
||||||
{
|
{
|
||||||
asm volatile("pause");
|
asm volatile("pause");
|
||||||
|
@ -45,22 +45,17 @@ Result<void> init()
|
|||||||
kinfoln("Current platform: %s", CPU::platform_string());
|
kinfoln("Current platform: %s", CPU::platform_string());
|
||||||
kinfoln("Current processor: %s", CPU::identify().value_or("(unknown)"));
|
kinfoln("Current processor: %s", CPU::identify().value_or("(unknown)"));
|
||||||
|
|
||||||
Timer::init();
|
|
||||||
|
|
||||||
kinfoln("Total memory: %s", to_dynamic_unit(MemoryManager::total()).release_value().chars());
|
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("Free memory: %s", to_dynamic_unit(MemoryManager::free()).release_value().chars());
|
||||||
kinfoln("Used memory: %s", to_dynamic_unit(MemoryManager::used()).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());
|
kinfoln("Reserved memory: %s", to_dynamic_unit(MemoryManager::reserved()).release_value().chars());
|
||||||
|
|
||||||
Thread::init();
|
|
||||||
Scheduler::init();
|
|
||||||
|
|
||||||
VFS::root_fs = TRY(TmpFS::FileSystem::create());
|
VFS::root_fs = TRY(TmpFS::FileSystem::create());
|
||||||
TRY(DeviceRegistry::init());
|
TRY(DeviceRegistry::init());
|
||||||
InitRD::populate_vfs();
|
InitRD::populate_vfs();
|
||||||
|
|
||||||
auto init = TRY(VFS::resolve_path("/bin/init", Credentials {}));
|
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();
|
Scheduler::new_kernel_thread(reap_thread, "[reap]").release_value();
|
||||||
|
|
||||||
@ -71,43 +66,36 @@ Result<void> init()
|
|||||||
},
|
},
|
||||||
{ .klass = 1 });
|
{ .klass = 1 });
|
||||||
|
|
||||||
CPU::platform_finish_init();
|
|
||||||
|
|
||||||
// Disable console logging before transferring control to userspace.
|
// Disable console logging before transferring control to userspace.
|
||||||
setup_log(log_debug_enabled(), log_serial_enabled(), false);
|
setup_log(log_debug_enabled(), log_serial_enabled(), false);
|
||||||
|
|
||||||
CPU::enable_interrupts();
|
init_thread->state = ThreadState::Runnable;
|
||||||
|
|
||||||
return {};
|
kernel_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] void init_wrapper()
|
[[noreturn]] void init_wrapper()
|
||||||
{
|
{
|
||||||
auto rc = init();
|
auto rc = init();
|
||||||
if (rc.has_error()) kerrorln("Runtime error: %s", rc.error_string());
|
if (rc.has_error()) kerrorln("Runtime error: %s", rc.error_string());
|
||||||
CPU::idle_loop();
|
kernel_exit();
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" [[noreturn]] void _start()
|
extern "C" [[noreturn]] void _start()
|
||||||
{
|
{
|
||||||
Init::check_magic();
|
Init::check_magic();
|
||||||
Init::early_init();
|
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();
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,8 @@ namespace Scheduler
|
|||||||
|
|
||||||
g_threads.append(thread);
|
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());
|
kinfoln("Created kernel thread: id %lu with ip %#lx and sp %#lx", thread->id, thread->ip(), thread->sp());
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
@ -109,11 +111,13 @@ namespace Scheduler
|
|||||||
return new_kernel_thread_impl(thread, name);
|
return new_kernel_thread_impl(thread, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<void> new_userspace_thread(SharedPtr<VFS::Inode> inode, const char* name)
|
Result<Thread*> new_userspace_thread(SharedPtr<VFS::Inode> inode, const char* name)
|
||||||
{
|
{
|
||||||
Thread* const thread = TRY(new_thread());
|
Thread* const thread = TRY(make<Thread>());
|
||||||
|
|
||||||
|
thread->state = ThreadState::None;
|
||||||
thread->is_kernel = false;
|
thread->is_kernel = false;
|
||||||
|
thread->id = 1;
|
||||||
thread->name = name;
|
thread->name = name;
|
||||||
thread->parent_id = 0;
|
thread->parent_id = 0;
|
||||||
thread->auth = Credentials { .uid = 0, .euid = 0, .suid = 0, .gid = 0, .egid = 0, .sgid = 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);
|
g_threads.append(thread);
|
||||||
|
|
||||||
return {};
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_thread(Thread* thread)
|
void add_thread(Thread* thread)
|
||||||
|
@ -13,7 +13,7 @@ namespace Scheduler
|
|||||||
Result<void> new_kernel_thread(void (*func)(void), const char* name);
|
Result<void> new_kernel_thread(void (*func)(void), const char* name);
|
||||||
Result<void> new_kernel_thread(void (*func)(void*), void* arg, const char* name);
|
Result<void> new_kernel_thread(void (*func)(void*), void* arg, const char* name);
|
||||||
|
|
||||||
Result<void> new_userspace_thread(SharedPtr<VFS::Inode> inode, const char* name);
|
Result<Thread*> new_userspace_thread(SharedPtr<VFS::Inode> inode, const char* name);
|
||||||
|
|
||||||
void add_thread(Thread* thread);
|
void add_thread(Thread* thread);
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ LinkedList<Thread> g_threads;
|
|||||||
|
|
||||||
void Thread::init()
|
void Thread::init()
|
||||||
{
|
{
|
||||||
g_next_id = 1;
|
g_next_id = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result<Thread*> new_thread()
|
Result<Thread*> new_thread()
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
enum class ThreadState
|
enum class ThreadState
|
||||||
{
|
{
|
||||||
|
None,
|
||||||
Idle,
|
Idle,
|
||||||
Runnable,
|
Runnable,
|
||||||
Sleeping,
|
Sleeping,
|
||||||
|
Loading…
Reference in New Issue
Block a user