Kernel/Userspace: Start initial work on userspace and syscalls
This commit is contained in:
44
kernel/kernel/Syscall.cpp
Normal file
44
kernel/kernel/Syscall.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <kernel/Debug.h>
|
||||
#include <kernel/kprint.h>
|
||||
#include <kernel/Syscall.h>
|
||||
|
||||
namespace Kernel
|
||||
{
|
||||
|
||||
int sys_test()
|
||||
{
|
||||
dprintln("hello");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_putc(void* ch)
|
||||
{
|
||||
kprint("{}", (char)(uintptr_t)ch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" int cpp_syscall_handler(int syscall, void* arg1, void* arg2, void* arg3)
|
||||
{
|
||||
(void)arg1;
|
||||
(void)arg2;
|
||||
(void)arg3;
|
||||
|
||||
int ret;
|
||||
switch (syscall)
|
||||
{
|
||||
case SYS_TEST:
|
||||
ret = sys_test();
|
||||
break;
|
||||
case SYS_PUTC:
|
||||
ret = sys_putc(arg1);
|
||||
break;
|
||||
default:
|
||||
ret = -1;
|
||||
dprintln("Unknown syscall");
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <kernel/Arch.h>
|
||||
#include <kernel/Debug.h>
|
||||
#include <kernel/FS/VirtualFileSystem.h>
|
||||
#include <kernel/GDT.h>
|
||||
@@ -14,6 +15,7 @@
|
||||
#include <kernel/Scheduler.h>
|
||||
#include <kernel/Serial.h>
|
||||
#include <kernel/Shell.h>
|
||||
#include <kernel/Syscall.h>
|
||||
#include <kernel/TTY.h>
|
||||
#include <kernel/VesaTerminalDriver.h>
|
||||
|
||||
@@ -75,6 +77,14 @@ namespace BAN::Formatter
|
||||
|
||||
}
|
||||
|
||||
extern "C" uintptr_t g_rodata_start;
|
||||
extern "C" uintptr_t g_rodata_end;
|
||||
|
||||
extern "C" uintptr_t g_userspace_start;
|
||||
extern "C" uintptr_t g_userspace_end;
|
||||
|
||||
extern void userspace_entry();
|
||||
|
||||
extern "C" void kernel_main()
|
||||
{
|
||||
using namespace Kernel;
|
||||
@@ -124,6 +134,50 @@ extern "C" void kernel_main()
|
||||
|
||||
MUST(Scheduler::initialize());
|
||||
Scheduler& scheduler = Scheduler::get();
|
||||
#if 1
|
||||
MUST(scheduler.add_thread(MUST(Thread::create(
|
||||
[] (void*)
|
||||
{
|
||||
MMU::get().allocate_range((uintptr_t)&g_userspace_start, (uintptr_t)&g_userspace_end - (uintptr_t)&g_userspace_start, MMU::Flags::UserSupervisor | MMU::Flags::Present);
|
||||
MMU::get().allocate_range((uintptr_t)&g_rodata_start, (uintptr_t)&g_rodata_end - (uintptr_t)&g_rodata_start, MMU::Flags::UserSupervisor | MMU::Flags::Present);
|
||||
|
||||
void* userspace_stack = kmalloc(4096, 4096);
|
||||
ASSERT(userspace_stack);
|
||||
MMU::get().allocate_page((uintptr_t)userspace_stack, MMU::Flags::UserSupervisor | MMU::Flags::ReadWrite | MMU::Flags::Present);
|
||||
|
||||
BOCHS_BREAK();
|
||||
|
||||
#if ARCH(x86_64)
|
||||
asm volatile(
|
||||
"pushq %0;"
|
||||
"pushq %1;"
|
||||
"pushfq;"
|
||||
"pushq %2;"
|
||||
"pushq %3;"
|
||||
"iretq;"
|
||||
:: "r"((uintptr_t)0x20 | 3), "r"((uintptr_t)userspace_stack + 4096), "r"((uintptr_t)0x18 | 3), "r"(userspace_entry)
|
||||
);
|
||||
#else
|
||||
asm volatile(
|
||||
"movl %0, %%eax;"
|
||||
"movw %%ax, %%ds;"
|
||||
"movw %%ax, %%es;"
|
||||
"movw %%ax, %%fs;"
|
||||
"movw %%ax, %%gs;"
|
||||
|
||||
"movl %1, %%esp;"
|
||||
"pushl %0;"
|
||||
"pushl %1;"
|
||||
"pushfl;"
|
||||
"pushl %2;"
|
||||
"pushl %3;"
|
||||
"iret;"
|
||||
:: "r"((uintptr_t)0x20 | 3), "r"((uintptr_t)userspace_stack + 4096), "r"((uintptr_t)0x18 | 3), "r"(userspace_entry)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
))));
|
||||
#else
|
||||
MUST(scheduler.add_thread(MUST(Thread::create(
|
||||
[](void* terminal_driver)
|
||||
{
|
||||
@@ -144,6 +198,7 @@ extern "C" void kernel_main()
|
||||
shell->run();
|
||||
}, tty1
|
||||
))));
|
||||
#endif
|
||||
scheduler.start();
|
||||
ASSERT(false);
|
||||
}
|
||||
Reference in New Issue
Block a user