Compare commits

...

3 Commits

Author SHA1 Message Date
Drew Galbraith 8d87791fa2 Differentiate syscall handler by number.
This causes us to panic on the unhandled exit syscall.
2023-05-29 13:06:43 -07:00
Drew Galbraith 6f5b65de30 Map user pages in the proper mode.
This causes the user code to execute succesfully.
However now we don't differentiate between syscalls so we pass right
over the exit syscall and continue executing until we fault.
2023-05-29 13:06:08 -07:00
Drew Galbraith 7184f527a0 Jump to user mode.
This instantly creates a page fault as we always map pages with ring 0
permissions.
2023-05-29 13:06:08 -07:00
9 changed files with 57 additions and 12 deletions

View File

@ -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

View File

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

View File

@ -1,3 +1,7 @@
#pragma once
#include <stdint.h>
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
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;
}

View File

@ -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);

View File

@ -6,6 +6,7 @@
#define PRESENT_BIT 0x1
#define READ_WRITE_BIT 0x2
#define USER_MODE_BIT 0x4;
#define SIGN_EXT 0xFFFF0000'00000000
#define RECURSIVE ((uint64_t)0x1FE)
#define PML_OFFSET 39
@ -79,23 +80,29 @@ void MapPage(uint64_t virt, uint64_t phys) {
panic("Allocating Over Existing Page: %m", virt);
}
uint64_t access_bits = PRESENT_BIT | READ_WRITE_BIT;
uint64_t higher_half = 0xffff8000'00000000;
if ((virt & higher_half) != higher_half) {
access_bits |= USER_MODE_BIT;
}
if (!PageDirectoryPointerLoaded(virt)) {
uint64_t page = phys_mem::AllocatePage();
*Pml4Entry(virt) = page | PRESENT_BIT | READ_WRITE_BIT;
*Pml4Entry(virt) = page | access_bits;
ZeroOutPage(PageDirectoryPointerEntry(virt));
}
if (!PageDirectoryLoaded(virt)) {
uint64_t page = phys_mem::AllocatePage();
*PageDirectoryPointerEntry(virt) = page | PRESENT_BIT | READ_WRITE_BIT;
*PageDirectoryPointerEntry(virt) = page | access_bits;
ZeroOutPage(PageDirectoryEntry(virt));
}
if (!PageTableLoaded(virt)) {
uint64_t page = phys_mem::AllocatePage();
*PageDirectoryEntry(virt) = page | PRESENT_BIT | READ_WRITE_BIT;
*PageDirectoryEntry(virt) = page | access_bits;
ZeroOutPage(PageTableEntry(virt));
}
*PageTableEntry(virt) = PageAlign(phys) | PRESENT_BIT | READ_WRITE_BIT;
*PageTableEntry(virt) = PageAlign(phys) | access_bits;
ZeroOutPage(reinterpret_cast<uint64_t*>(virt));
}

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 "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);
}

View File

@ -3,6 +3,7 @@
#include <stdint.h>
#include "debug/debug.h"
#include "include/zcall.h"
#include "scheduler/scheduler.h"
#define EFER 0xC0000080
@ -53,5 +54,12 @@ void InitSyscall() {
}
extern "C" void SyscallHandler(uint64_t call_id, char* message) {
dbgln(message);
Thread& thread = sched::CurrentThread();
switch (call_id) {
case Z_DEBUG_PRINT:
dbgln("[%u.%u] %s", thread.pid(), thread.tid(), message);
break;
default:
panic("Unhandled syscall number: %u", call_id);
}
}