Jump to user mode.
This instantly creates a page fault as we always map pages with ring 0 permissions.
This commit is contained in:
parent
aefb4f082b
commit
7184f527a0
|
@ -11,6 +11,7 @@ add_executable(zion
|
|||
memory/paging_util.cpp
|
||||
memory/physical_memory.cpp
|
||||
scheduler/context_switch.s
|
||||
scheduler/jump_user_space.s
|
||||
scheduler/process.cpp
|
||||
scheduler/scheduler.cpp
|
||||
scheduler/thread.cpp
|
||||
|
|
|
@ -90,3 +90,5 @@ void InitGdt() {
|
|||
"ltr %%ax;" ::
|
||||
: "rax");
|
||||
}
|
||||
|
||||
void SetRsp0(uint64_t rsp0) { gTaskStateSegment.rsp0 = rsp0; }
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void InitGdt();
|
||||
|
||||
void SetRsp0(uint64_t rsp0);
|
||||
|
|
|
@ -56,7 +56,7 @@ void badmemcpy(uint64_t base, uint64_t offset, uint64_t dest) {
|
|||
|
||||
} // namespace
|
||||
|
||||
void LoadElfProgram(uint64_t base, uint64_t offset) {
|
||||
uint64_t LoadElfProgram(uint64_t base, uint64_t offset) {
|
||||
Elf64Header* header = reinterpret_cast<Elf64Header*>(base);
|
||||
dbgln("phoff: %u phnum: %u", header->phoff, header->phnum);
|
||||
Elf64ProgramHeader* programs =
|
||||
|
@ -71,4 +71,5 @@ void LoadElfProgram(uint64_t base, uint64_t offset) {
|
|||
EnsureResident(program.vaddr, program.memsz);
|
||||
badmemcpy(base + program.offset, program.filesz, program.vaddr);
|
||||
}
|
||||
return header->entry;
|
||||
}
|
||||
|
|
|
@ -2,4 +2,5 @@
|
|||
|
||||
#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);
|
||||
|
|
|
@ -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
|
|
@ -1,12 +1,16 @@
|
|||
#include "scheduler/thread.h"
|
||||
|
||||
#include "common/gdt.h"
|
||||
#include "debug/debug.h"
|
||||
#include "loader/elf_loader.h"
|
||||
#include "memory/paging_util.h"
|
||||
#include "scheduler/process.h"
|
||||
#include "scheduler/scheduler.h"
|
||||
|
||||
namespace {
|
||||
|
||||
extern "C" void jump_user_space(uint64_t rip, uint64_t rsp);
|
||||
|
||||
extern "C" void thread_init() {
|
||||
asm("sti");
|
||||
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(); }
|
||||
|
||||
void Thread::Init() {
|
||||
LoadElfProgram(elf_ptr_, 0);
|
||||
while (true) {
|
||||
dbgln("[%u.%u]", pid(), id_);
|
||||
sched::Yield();
|
||||
}
|
||||
dbgln("[%u.%u]", pid(), id_);
|
||||
uint64_t rip = LoadElfProgram(elf_ptr_, 0);
|
||||
uint64_t rsp = 0x80000000;
|
||||
EnsureResident(rsp - 1, 1);
|
||||
SetRsp0(rsp0_start_);
|
||||
jump_user_space(rip, rsp);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue