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;
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);
~Process();
[[noreturn]] void exit();
BAN::ErrorOr<Thread*> add_thread(entry_t, void*);
void add_thread(Thread*);
void on_thread_exit(Thread&);
BAN::ErrorOr<void> init_stdio();
@ -60,6 +60,7 @@ namespace Kernel
private:
Process(pid_t);
static Process* create_process();
static void register_process(Process*);
BAN::ErrorOr<BAN::String> absolute_path_of(BAN::StringView) const;

View File

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

View File

@ -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
);
}

View File

@ -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*> 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<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);
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)

View File

@ -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")

View File

@ -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
);
}

View File

@ -29,6 +29,19 @@ namespace Kernel
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)
: 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_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));
);
}