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;
|
||||
|
||||
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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{}
|
||||
|
|
|
@ -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));
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue