Jump to user mode.

This instantly creates a page fault as we always map pages with ring 0
permissions.
This commit is contained in:
Drew Galbraith 2023-05-29 12:44:26 -07:00
parent aefb4f082b
commit 7184f527a0
7 changed files with 37 additions and 7 deletions

View File

@ -11,6 +11,7 @@ add_executable(zion
memory/paging_util.cpp memory/paging_util.cpp
memory/physical_memory.cpp memory/physical_memory.cpp
scheduler/context_switch.s scheduler/context_switch.s
scheduler/jump_user_space.s
scheduler/process.cpp scheduler/process.cpp
scheduler/scheduler.cpp scheduler/scheduler.cpp
scheduler/thread.cpp scheduler/thread.cpp

View File

@ -90,3 +90,5 @@ void InitGdt() {
"ltr %%ax;" :: "ltr %%ax;" ::
: "rax"); : "rax");
} }
void SetRsp0(uint64_t rsp0) { gTaskStateSegment.rsp0 = rsp0; }

View File

@ -1,3 +1,7 @@
#pragma once #pragma once
#include <stdint.h>
void InitGdt(); void InitGdt();
void SetRsp0(uint64_t rsp0);

View File

@ -56,7 +56,7 @@ void badmemcpy(uint64_t base, uint64_t offset, uint64_t dest) {
} // namespace } // namespace
void LoadElfProgram(uint64_t base, uint64_t offset) { uint64_t LoadElfProgram(uint64_t base, uint64_t offset) {
Elf64Header* header = reinterpret_cast<Elf64Header*>(base); Elf64Header* header = reinterpret_cast<Elf64Header*>(base);
dbgln("phoff: %u phnum: %u", header->phoff, header->phnum); dbgln("phoff: %u phnum: %u", header->phoff, header->phnum);
Elf64ProgramHeader* programs = Elf64ProgramHeader* programs =
@ -71,4 +71,5 @@ void LoadElfProgram(uint64_t base, uint64_t offset) {
EnsureResident(program.vaddr, program.memsz); EnsureResident(program.vaddr, program.memsz);
badmemcpy(base + program.offset, program.filesz, program.vaddr); badmemcpy(base + program.offset, program.filesz, program.vaddr);
} }
return header->entry;
} }

View File

@ -2,4 +2,5 @@
#include <stdint.h> #include <stdint.h>
void LoadElfProgram(uint64_t base, uint64_t length); // Loads the elf program and returns its entry point.
uint64_t LoadElfProgram(uint64_t base, uint64_t length);

View File

@ -0,0 +1,16 @@
.global jump_user_space
// rdi - entry point, rsi - user stack
jump_user_space:
cli
mov $0x23, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
pushq $0x23 # ss
pushq %rsi
pushf # Can we just push 0 for flags?
pushq $0x1B # cs
pushq %rdi
iretq

View File

@ -1,12 +1,16 @@
#include "scheduler/thread.h" #include "scheduler/thread.h"
#include "common/gdt.h"
#include "debug/debug.h" #include "debug/debug.h"
#include "loader/elf_loader.h" #include "loader/elf_loader.h"
#include "memory/paging_util.h"
#include "scheduler/process.h" #include "scheduler/process.h"
#include "scheduler/scheduler.h" #include "scheduler/scheduler.h"
namespace { namespace {
extern "C" void jump_user_space(uint64_t rip, uint64_t rsp);
extern "C" void thread_init() { extern "C" void thread_init() {
asm("sti"); asm("sti");
sched::CurrentThread().Init(); sched::CurrentThread().Init();
@ -36,9 +40,10 @@ Thread::Thread(Process* proc, uint64_t tid, uint64_t elf_ptr)
uint64_t Thread::pid() { return process_->id(); } uint64_t Thread::pid() { return process_->id(); }
void Thread::Init() { void Thread::Init() {
LoadElfProgram(elf_ptr_, 0); dbgln("[%u.%u]", pid(), id_);
while (true) { uint64_t rip = LoadElfProgram(elf_ptr_, 0);
dbgln("[%u.%u]", pid(), id_); uint64_t rsp = 0x80000000;
sched::Yield(); EnsureResident(rsp - 1, 1);
} SetRsp0(rsp0_start_);
jump_user_space(rip, rsp);
} }