Kernel: Cleanup process creation for userspace

This commit is contained in:
Bananymous 2023-04-22 16:43:44 +03:00
parent 8001493df3
commit 1406a75a92
8 changed files with 47 additions and 70 deletions

View File

@ -23,13 +23,13 @@ namespace Kernel
using entry_t = Thread::entry_t; using entry_t = Thread::entry_t;
public: public:
static BAN::ErrorOr<Process*> create_kernel(entry_t, void*); static Process* create_kernel(entry_t, void*);
static BAN::ErrorOr<Process*> create_userspace(BAN::StringView); static BAN::ErrorOr<Process*> create_userspace(BAN::StringView);
~Process(); ~Process();
[[noreturn]] void exit(); [[noreturn]] void exit();
BAN::ErrorOr<Thread*> add_thread(entry_t, void*); void add_thread(Thread*);
void on_thread_exit(Thread&); void on_thread_exit(Thread&);
BAN::ErrorOr<void> init_stdio(); BAN::ErrorOr<void> init_stdio();
@ -60,6 +60,7 @@ namespace Kernel
private: private:
Process(pid_t); Process(pid_t);
static Process* create_process(); static Process* create_process();
static void register_process(Process*);
BAN::ErrorOr<BAN::String> absolute_path_of(BAN::StringView) const; BAN::ErrorOr<BAN::String> absolute_path_of(BAN::StringView) const;

View File

@ -27,6 +27,7 @@ namespace Kernel
public: public:
static BAN::ErrorOr<Thread*> create(entry_t, void*, Process*); static BAN::ErrorOr<Thread*> create(entry_t, void*, Process*);
static BAN::ErrorOr<Thread*> create_userspace(uintptr_t, Process*);
~Thread(); ~Thread();
void jump_userspace(uintptr_t rip); void jump_userspace(uintptr_t rip);

View File

@ -60,7 +60,7 @@ namespace Kernel
void DeviceManager::initialize_updater() void DeviceManager::initialize_updater()
{ {
MUST(Process::create_kernel( Process::create_kernel(
[](void*) [](void*)
{ {
while (true) while (true)
@ -68,7 +68,7 @@ namespace Kernel
DeviceManager::get().update(); DeviceManager::get().update();
PIT::sleep(1); PIT::sleep(1);
} }
}, nullptr) }, nullptr
); );
} }

View File

@ -20,19 +20,26 @@ namespace Kernel
static pid_t s_next_pid = 1; static pid_t s_next_pid = 1;
auto* process = new Process(s_next_pid++); auto* process = new Process(s_next_pid++);
ASSERT(process); ASSERT(process);
return process;
}
void Process::register_process(Process* process)
{
s_process_lock.lock(); s_process_lock.lock();
MUST(s_processes.push_back(process)); MUST(s_processes.push_back(process));
s_process_lock.unlock(); s_process_lock.unlock();
return process; for (auto* thread : process->m_threads)
MUST(Scheduler::get().add_thread(thread));
} }
BAN::ErrorOr<Process*> Process::create_kernel(entry_t entry, void* data) Process* Process::create_kernel(entry_t entry, void* data)
{ {
auto* process = create_process(); auto* process = create_process();
TRY(process->m_working_directory.push_back('/')); MUST(process->m_working_directory.push_back('/'));
TRY(process->add_thread(entry, data)); auto* thread = MUST(Thread::create(entry, data, process));
process->add_thread(thread);
register_process(process);
return process; return process;
} }
@ -41,8 +48,8 @@ namespace Kernel
auto* elf = TRY(LibELF::ELF::load_from_file(path)); auto* elf = TRY(LibELF::ELF::load_from_file(path));
auto* process = create_process(); auto* process = create_process();
TRY(process->m_working_directory.push_back('/')); MUST(process->m_working_directory.push_back('/'));
TRY(process->init_stdio()); MUST(process->init_stdio());
process->m_mmu = new MMU(); process->m_mmu = new MMU();
ASSERT(process->m_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->map_page_at(addr, page * 4096, MMU::Flags::UserSupervisor | MMU::Flags::ReadWrite | MMU::Flags::Present);
} }
process->m_mmu->load(); 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); 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(); 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; break;
} }
default: default:
@ -82,19 +82,12 @@ namespace Kernel
} }
} }
TRY(process->add_thread( auto* thread = MUST(Thread::create_userspace(elf_file_header.e_entry, process));
[](void* entry) process->add_thread(thread);
{
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
));
delete elf; delete elf;
register_process(process);
return process; return process;
} }
@ -109,19 +102,10 @@ namespace Kernel
exit(); exit();
} }
BAN::ErrorOr<Thread*> 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); LockGuard _(m_lock);
TRY(m_threads.push_back(thread)); MUST(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;
} }
void Process::on_thread_exit(Thread& thread) void Process::on_thread_exit(Thread& thread)

View File

@ -327,18 +327,6 @@ argument_done:
if (arguments.empty()) 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") else if (arguments.front() == "date")
{ {
@ -410,7 +398,9 @@ argument_done:
SpinLock spinlock; SpinLock spinlock;
thread_data_t thread_data = { this, spinlock, arguments }; thread_data_t thread_data = { this, spinlock, arguments };
spinlock.lock(); 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()); while (spinlock.is_locked());
} }
else if (arguments.front() == "memory") else if (arguments.front() == "memory")

View File

@ -55,7 +55,7 @@ namespace Kernel
m_name = BAN::String::formatted("tty{}", minor(m_rdev)); m_name = BAN::String::formatted("tty{}", minor(m_rdev));
DeviceManager::get().add_device(this); DeviceManager::get().add_device(this);
MUST(Process::create_kernel( Process::create_kernel(
[](void* tty_) [](void* tty_)
{ {
TTY* tty = (TTY*)tty_; TTY* tty = (TTY*)tty_;
@ -66,7 +66,7 @@ namespace Kernel
MUST(Process::current().read(fd, &event, sizeof(event))); MUST(Process::current().read(fd, &event, sizeof(event)));
tty->on_key(event); tty->on_key(event);
} }
}, this) }, this
); );
} }

View File

@ -29,6 +29,19 @@ namespace Kernel
return thread; return thread;
} }
BAN::ErrorOr<Thread*> 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) Thread::Thread(pid_t tid, Process* process)
: m_tid(tid), m_process(process) : m_tid(tid), m_process(process)
{} {}

View File

@ -102,9 +102,6 @@ namespace BAN::Formatter
extern "C" uintptr_t g_kernel_start; extern "C" uintptr_t g_kernel_start;
extern "C" uintptr_t g_kernel_end; extern "C" uintptr_t g_kernel_end;
extern void userspace_entry();
static void jump_userspace();
static void init2(void*); static void init2(void*);
extern "C" void kernel_main() extern "C" void kernel_main()
@ -162,7 +159,7 @@ extern "C" void kernel_main()
MUST(Scheduler::initialize()); MUST(Scheduler::initialize());
Scheduler& scheduler = Scheduler::get(); Scheduler& scheduler = Scheduler::get();
MUST(Process::create_kernel(init2, tty1)); Process::create_kernel(init2, tty1);
scheduler.start(); scheduler.start();
ASSERT_NOT_REACHED(); ASSERT_NOT_REACHED();
@ -183,10 +180,10 @@ static void init2(void* tty1)
((TTY*)tty1)->initialize_device(); ((TTY*)tty1)->initialize_device();
jump_userspace(); MUST(Process::create_userspace("/bin/test"sv));
return; return;
MUST(Process::create_kernel( Process::create_kernel(
[](void*) [](void*)
{ {
MUST(Process::current().init_stdio()); MUST(Process::current().init_stdio());
@ -194,14 +191,5 @@ static void init2(void* tty1)
ASSERT(shell); ASSERT(shell);
shell->run(); shell->run();
}, nullptr }, 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));
} }