From 1406a75a92ec4c1a375dd435eb4ef07e7616c51b Mon Sep 17 00:00:00 2001 From: Bananymous Date: Sat, 22 Apr 2023 16:43:44 +0300 Subject: [PATCH] Kernel: Cleanup process creation for userspace --- kernel/include/kernel/Process.h | 5 +-- kernel/include/kernel/Thread.h | 1 + kernel/kernel/DeviceManager.cpp | 4 +-- kernel/kernel/Process.cpp | 54 ++++++++++++--------------------- kernel/kernel/Shell.cpp | 16 ++-------- kernel/kernel/Terminal/TTY.cpp | 4 +-- kernel/kernel/Thread.cpp | 13 ++++++++ kernel/kernel/kernel.cpp | 20 +++--------- 8 files changed, 47 insertions(+), 70 deletions(-) diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 4b392c74..ab0fa707 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -23,13 +23,13 @@ namespace Kernel using entry_t = Thread::entry_t; public: - static BAN::ErrorOr create_kernel(entry_t, void*); + static Process* create_kernel(entry_t, void*); static BAN::ErrorOr create_userspace(BAN::StringView); ~Process(); [[noreturn]] void exit(); - BAN::ErrorOr add_thread(entry_t, void*); + void add_thread(Thread*); void on_thread_exit(Thread&); BAN::ErrorOr init_stdio(); @@ -60,6 +60,7 @@ namespace Kernel private: Process(pid_t); static Process* create_process(); + static void register_process(Process*); BAN::ErrorOr absolute_path_of(BAN::StringView) const; diff --git a/kernel/include/kernel/Thread.h b/kernel/include/kernel/Thread.h index e0886ac7..9a1dd539 100644 --- a/kernel/include/kernel/Thread.h +++ b/kernel/include/kernel/Thread.h @@ -27,6 +27,7 @@ namespace Kernel public: static BAN::ErrorOr create(entry_t, void*, Process*); + static BAN::ErrorOr create_userspace(uintptr_t, Process*); ~Thread(); void jump_userspace(uintptr_t rip); diff --git a/kernel/kernel/DeviceManager.cpp b/kernel/kernel/DeviceManager.cpp index 6b2dfd9d..fb4f5588 100644 --- a/kernel/kernel/DeviceManager.cpp +++ b/kernel/kernel/DeviceManager.cpp @@ -60,7 +60,7 @@ namespace Kernel void DeviceManager::initialize_updater() { - MUST(Process::create_kernel( + Process::create_kernel( [](void*) { while (true) @@ -68,7 +68,7 @@ namespace Kernel DeviceManager::get().update(); PIT::sleep(1); } - }, nullptr) + }, nullptr ); } diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 02a1019a..f07f4138 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -20,19 +20,26 @@ namespace Kernel static pid_t s_next_pid = 1; auto* process = new Process(s_next_pid++); ASSERT(process); + return process; + } + void Process::register_process(Process* process) + { s_process_lock.lock(); MUST(s_processes.push_back(process)); s_process_lock.unlock(); - return process; + for (auto* thread : process->m_threads) + MUST(Scheduler::get().add_thread(thread)); } - BAN::ErrorOr Process::create_kernel(entry_t entry, void* data) + Process* Process::create_kernel(entry_t entry, void* data) { auto* process = create_process(); - TRY(process->m_working_directory.push_back('/')); - TRY(process->add_thread(entry, data)); + MUST(process->m_working_directory.push_back('/')); + auto* thread = MUST(Thread::create(entry, data, process)); + process->add_thread(thread); + register_process(process); return process; } @@ -41,8 +48,8 @@ namespace Kernel auto* elf = TRY(LibELF::ELF::load_from_file(path)); auto* process = create_process(); - TRY(process->m_working_directory.push_back('/')); - TRY(process->init_stdio()); + MUST(process->m_working_directory.push_back('/')); + MUST(process->init_stdio()); process->m_mmu = new MMU(); ASSERT(process->m_mmu); @@ -65,16 +72,9 @@ namespace Kernel process->m_mmu->map_page_at(addr, page * 4096, MMU::Flags::UserSupervisor | MMU::Flags::ReadWrite | MMU::Flags::Present); } process->m_mmu->load(); - memset((void*)elf_program_header.p_vaddr, 0, elf_program_header.p_memsz); memcpy((void*)elf_program_header.p_vaddr, elf->data() + elf_program_header.p_offset, elf_program_header.p_filesz); + memset((void*)(elf_program_header.p_vaddr + elf_program_header.p_filesz), 0, elf_program_header.p_memsz); Process::current().mmu().load(); - - dwarnln("mapped {8H}->{8H} to {8H}->{8H}", - elf_program_header.p_offset, - elf_program_header.p_offset + elf_program_header.p_filesz, - elf_program_header.p_vaddr, - elf_program_header.p_vaddr + elf_program_header.p_memsz - ); break; } default: @@ -82,19 +82,12 @@ namespace Kernel } } - TRY(process->add_thread( - [](void* entry) - { - Thread& current = Thread::current(); - current.process().m_mmu->map_range(current.stack_base(), current.stack_size(), MMU::Flags::UserSupervisor | MMU::Flags::ReadWrite | MMU::Flags::Present); - current.process().m_mmu->load(); - current.jump_userspace((uintptr_t)entry); - ASSERT_NOT_REACHED(); - }, (void*)elf_file_header.e_entry - )); + auto* thread = MUST(Thread::create_userspace(elf_file_header.e_entry, process)); + process->add_thread(thread); delete elf; + register_process(process); return process; } @@ -109,19 +102,10 @@ namespace Kernel exit(); } - BAN::ErrorOr Process::add_thread(entry_t entry, void* data) + void Process::add_thread(Thread* thread) { - Thread* thread = TRY(Thread::create(entry, data, this)); - LockGuard _(m_lock); - TRY(m_threads.push_back(thread)); - if (auto res = Scheduler::get().add_thread(thread); res.is_error()) - { - m_threads.pop_back(); - return res.release_error(); - } - - return thread; + MUST(m_threads.push_back(thread)); } void Process::on_thread_exit(Thread& thread) diff --git a/kernel/kernel/Shell.cpp b/kernel/kernel/Shell.cpp index 7641dc29..00a523ff 100644 --- a/kernel/kernel/Shell.cpp +++ b/kernel/kernel/Shell.cpp @@ -327,18 +327,6 @@ argument_done: if (arguments.empty()) { - } - else if (arguments.front() == "oof") - { - SpinLock lock; - for (int i = 0; i < 100; i++) - { - lock.lock(); - MUST(Process::create_kernel([](void*) { MUST(Process::current().init_stdio()); TTY_PRINTLN("####"); Process::current().exit(); }, nullptr)); - PIT::sleep(5); - kmalloc_dump_info(); - lock.unlock(); - } } else if (arguments.front() == "date") { @@ -410,7 +398,9 @@ argument_done: SpinLock spinlock; thread_data_t thread_data = { this, spinlock, arguments }; spinlock.lock(); - TRY(Process::current().add_thread(function, &thread_data)); + + auto* thread = TRY(Thread::create(function, &thread_data, &Process::current())); + Process::current().add_thread(thread); while (spinlock.is_locked()); } else if (arguments.front() == "memory") diff --git a/kernel/kernel/Terminal/TTY.cpp b/kernel/kernel/Terminal/TTY.cpp index dd70c74d..74ac9c28 100644 --- a/kernel/kernel/Terminal/TTY.cpp +++ b/kernel/kernel/Terminal/TTY.cpp @@ -55,7 +55,7 @@ namespace Kernel m_name = BAN::String::formatted("tty{}", minor(m_rdev)); DeviceManager::get().add_device(this); - MUST(Process::create_kernel( + Process::create_kernel( [](void* tty_) { TTY* tty = (TTY*)tty_; @@ -66,7 +66,7 @@ namespace Kernel MUST(Process::current().read(fd, &event, sizeof(event))); tty->on_key(event); } - }, this) + }, this ); } diff --git a/kernel/kernel/Thread.cpp b/kernel/kernel/Thread.cpp index 7287daf4..666fb46b 100644 --- a/kernel/kernel/Thread.cpp +++ b/kernel/kernel/Thread.cpp @@ -29,6 +29,19 @@ namespace Kernel return thread; } + BAN::ErrorOr Thread::create_userspace(uintptr_t entry, Process* process) + { + Thread* thread = TRY(Thread::create( + [](void* entry) + { + Thread::current().jump_userspace((uintptr_t)entry); + ASSERT_NOT_REACHED(); + }, (void*)entry, process + )); + process->mmu().map_range(thread->stack_base(), thread->stack_size(), MMU::Flags::UserSupervisor | MMU::Flags::ReadWrite | MMU::Flags::Present); + return thread; + } + Thread::Thread(pid_t tid, Process* process) : m_tid(tid), m_process(process) {} diff --git a/kernel/kernel/kernel.cpp b/kernel/kernel/kernel.cpp index 0acccead..79481d5d 100644 --- a/kernel/kernel/kernel.cpp +++ b/kernel/kernel/kernel.cpp @@ -102,9 +102,6 @@ namespace BAN::Formatter extern "C" uintptr_t g_kernel_start; extern "C" uintptr_t g_kernel_end; -extern void userspace_entry(); -static void jump_userspace(); - static void init2(void*); extern "C" void kernel_main() @@ -162,7 +159,7 @@ extern "C" void kernel_main() MUST(Scheduler::initialize()); Scheduler& scheduler = Scheduler::get(); - MUST(Process::create_kernel(init2, tty1)); + Process::create_kernel(init2, tty1); scheduler.start(); ASSERT_NOT_REACHED(); @@ -183,10 +180,10 @@ static void init2(void* tty1) ((TTY*)tty1)->initialize_device(); - jump_userspace(); + MUST(Process::create_userspace("/bin/test"sv)); return; - MUST(Process::create_kernel( + Process::create_kernel( [](void*) { MUST(Process::current().init_stdio()); @@ -194,14 +191,5 @@ static void init2(void* tty1) ASSERT(shell); shell->run(); }, nullptr - )); -} - -static void jump_userspace() -{ - using namespace Kernel; - - MMU::get().map_range((uintptr_t)&g_kernel_start, (uintptr_t)&g_kernel_end - (uintptr_t)&g_kernel_start, MMU::Flags::UserSupervisor | MMU::Flags::Present); - - MUST(Process::create_userspace("/bin/test"sv)); + ); }