forked from Bananymous/banan-os
Kernel: Cleanup process creation for userspace
This commit is contained in:
parent
8001493df3
commit
1406a75a92
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -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));
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue