Compare commits
No commits in common. "aefb4f082bd435aed4f70dfef4620cc49004c462" and "d3024211a76bdaf1d220f686bb47447c21b69b38" have entirely different histories.
aefb4f082b
...
d3024211a7
3
.gdbinit
3
.gdbinit
|
|
@ -1,4 +1,3 @@
|
||||||
source ~/.gdbinit-gef.py
|
target remote localhost:1234
|
||||||
gef-remote --qemu-user --qemu-binary=builddbg/zion/zion localhost 1234
|
|
||||||
file builddbg/zion/zion
|
file builddbg/zion/zion
|
||||||
break zion
|
break zion
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS True)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS True)
|
||||||
|
|
||||||
add_subdirectory(zion)
|
add_subdirectory(zion)
|
||||||
add_subdirectory(sys)
|
|
||||||
|
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT disk.img
|
OUTPUT disk.img
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ echo "Loopback device: ${dev}"
|
||||||
cleanup() {
|
cleanup() {
|
||||||
umount efi
|
umount efi
|
||||||
rm -rf efi
|
rm -rf efi
|
||||||
losetup -d $dev
|
|
||||||
}
|
}
|
||||||
trap cleanup EXIT
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
|
@ -36,7 +35,5 @@ cp /usr/share/limine/BOOTX64.EFI efi/EFI/BOOT
|
||||||
cp /usr/share/limine/limine.sys efi/
|
cp /usr/share/limine/limine.sys efi/
|
||||||
cp ../zion/boot/limine.cfg efi/
|
cp ../zion/boot/limine.cfg efi/
|
||||||
cp zion/zion efi/
|
cp zion/zion efi/
|
||||||
mkdir -p efi/sys
|
|
||||||
cp sys/test efi/sys/test
|
|
||||||
|
|
||||||
chown drew:drew $1
|
chown drew:drew $1
|
||||||
|
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
|
|
||||||
set(_COMPILE_FLAGS "-ffreestanding -mgeneral-regs-only")
|
|
||||||
set(_LINK_FLAGS "-nostdlib")
|
|
||||||
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
|
|
||||||
|
|
||||||
add_executable(test
|
|
||||||
test.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(test
|
|
||||||
zion_lib)
|
|
||||||
|
|
||||||
set_target_properties(test
|
|
||||||
PROPERTIES
|
|
||||||
COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${_COMPILE_FLAGS}"
|
|
||||||
LINK_FLAGS "${CMAKE_EXE_LINK_FLAGS} ${_LINK_FLAGS}"
|
|
||||||
)
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
#include "zcall.h"
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
ZDebug("Testing");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
@ -5,8 +5,6 @@ add_executable(zion
|
||||||
debug/debug.cpp
|
debug/debug.cpp
|
||||||
interrupt/interrupt.cpp
|
interrupt/interrupt.cpp
|
||||||
interrupt/interrupt_enter.s
|
interrupt/interrupt_enter.s
|
||||||
loader/elf_loader.cpp
|
|
||||||
loader/init_loader.cpp
|
|
||||||
memory/kernel_heap.cpp
|
memory/kernel_heap.cpp
|
||||||
memory/paging_util.cpp
|
memory/paging_util.cpp
|
||||||
memory/physical_memory.cpp
|
memory/physical_memory.cpp
|
||||||
|
|
@ -14,8 +12,6 @@ add_executable(zion
|
||||||
scheduler/process.cpp
|
scheduler/process.cpp
|
||||||
scheduler/scheduler.cpp
|
scheduler/scheduler.cpp
|
||||||
scheduler/thread.cpp
|
scheduler/thread.cpp
|
||||||
syscall/syscall.cpp
|
|
||||||
syscall/syscall_enter.s
|
|
||||||
zion.cpp)
|
zion.cpp)
|
||||||
|
|
||||||
target_include_directories(zion
|
target_include_directories(zion
|
||||||
|
|
@ -52,17 +48,3 @@ set_target_properties(zion
|
||||||
COMPILE_FLAGS "${_Z_COMPILE_FLAGS}"
|
COMPILE_FLAGS "${_Z_COMPILE_FLAGS}"
|
||||||
LINK_FLAGS "${_Z_LINK_FLAGS}"
|
LINK_FLAGS "${_Z_LINK_FLAGS}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
add_library(zion_lib STATIC
|
|
||||||
usr/crt0.s
|
|
||||||
usr/zcall.cpp)
|
|
||||||
|
|
||||||
target_include_directories(zion_lib
|
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
|
||||||
|
|
||||||
set_target_properties(zion_lib
|
|
||||||
PROPERTIES
|
|
||||||
COMPILE_FLAGS "${_Z_COMPILE_FLAGS}")
|
|
||||||
|
|
|
||||||
|
|
@ -25,15 +25,4 @@ uint64_t GetHigherHalfDirectMap() {
|
||||||
return gHhdmRequest.response->offset;
|
return gHhdmRequest.response->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static volatile struct limine_module_request gModuleRequest {
|
|
||||||
.id = LIMINE_MODULE_REQUEST, .revision = 0, .response = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
const limine_module_response& GetModules() {
|
|
||||||
if (!gModuleRequest.response) {
|
|
||||||
panic("No module response from limine");
|
|
||||||
}
|
|
||||||
return *gModuleRequest.response;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace boot
|
} // namespace boot
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,4 @@ namespace boot {
|
||||||
const limine_memmap_response& GetMemoryMap();
|
const limine_memmap_response& GetMemoryMap();
|
||||||
uint64_t GetHigherHalfDirectMap();
|
uint64_t GetHigherHalfDirectMap();
|
||||||
|
|
||||||
const limine_module_response& GetModules();
|
|
||||||
|
|
||||||
} // namespace boot
|
} // namespace boot
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
TIMEOUT=0
|
TIMEOUT=0
|
||||||
|
|
||||||
:AcadiaOS
|
:AcadiaOS
|
||||||
|
|
||||||
PROTOCOL=limine
|
PROTOCOL=limine
|
||||||
|
|
||||||
KERNEL_PATH=boot:///zion
|
KERNEL_PATH=boot:///zion
|
||||||
MODULE_PATH=boot:///sys/test
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#define Z_DEBUG_PRINT 100
|
|
||||||
|
|
||||||
uint64_t ZDebug(const char* message);
|
|
||||||
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
#include "loader/elf_loader.h"
|
|
||||||
|
|
||||||
#include "debug/debug.h"
|
|
||||||
#include "memory/paging_util.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char ident[16];
|
|
||||||
uint16_t type;
|
|
||||||
uint16_t machine;
|
|
||||||
uint32_t version;
|
|
||||||
uint64_t entry;
|
|
||||||
uint64_t phoff;
|
|
||||||
uint64_t shoff;
|
|
||||||
uint32_t flags;
|
|
||||||
uint16_t ehsize;
|
|
||||||
uint16_t phentsize;
|
|
||||||
uint16_t phnum;
|
|
||||||
uint16_t shentsize;
|
|
||||||
uint16_t shnum;
|
|
||||||
uint16_t shstrndx;
|
|
||||||
} Elf64Header;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t name;
|
|
||||||
uint32_t type;
|
|
||||||
uint64_t flags;
|
|
||||||
uint64_t addr;
|
|
||||||
uint64_t offset;
|
|
||||||
uint64_t size;
|
|
||||||
uint32_t link;
|
|
||||||
uint32_t info;
|
|
||||||
uint64_t addralign;
|
|
||||||
uint64_t entsize;
|
|
||||||
} Elf64SectionHeader;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t type;
|
|
||||||
uint32_t flags;
|
|
||||||
uint64_t offset;
|
|
||||||
uint64_t vaddr;
|
|
||||||
uint64_t paddr;
|
|
||||||
uint64_t filesz;
|
|
||||||
uint64_t memsz;
|
|
||||||
uint64_t align;
|
|
||||||
} Elf64ProgramHeader;
|
|
||||||
|
|
||||||
void badmemcpy(uint64_t base, uint64_t offset, uint64_t dest) {
|
|
||||||
uint8_t* ptr = reinterpret_cast<uint8_t*>(base);
|
|
||||||
uint8_t* dest_ptr = reinterpret_cast<uint8_t*>(dest);
|
|
||||||
for (uint64_t i = 0; i < offset; i++) {
|
|
||||||
dest_ptr[i] = ptr[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void LoadElfProgram(uint64_t base, uint64_t offset) {
|
|
||||||
Elf64Header* header = reinterpret_cast<Elf64Header*>(base);
|
|
||||||
dbgln("phoff: %u phnum: %u", header->phoff, header->phnum);
|
|
||||||
Elf64ProgramHeader* programs =
|
|
||||||
reinterpret_cast<Elf64ProgramHeader*>(base + header->phoff);
|
|
||||||
for (uint64_t i = 0; i < header->phnum; i++) {
|
|
||||||
Elf64ProgramHeader& program = programs[i];
|
|
||||||
dbgln(
|
|
||||||
"prog: type: %u, flags: %u, offset: %u\n vaddr: %m, paddr: %m\n "
|
|
||||||
"filesz: %u, memsz: %u, align: %u",
|
|
||||||
program.type, program.flags, program.offset, program.vaddr,
|
|
||||||
program.paddr, program.filesz, program.memsz, program.align);
|
|
||||||
EnsureResident(program.vaddr, program.memsz);
|
|
||||||
badmemcpy(base + program.offset, program.filesz, program.vaddr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
void LoadElfProgram(uint64_t base, uint64_t length);
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
#include "loader/init_loader.h"
|
|
||||||
|
|
||||||
#include "boot/boot_info.h"
|
|
||||||
#include "debug/debug.h"
|
|
||||||
#include "loader/elf_loader.h"
|
|
||||||
#include "scheduler/process.h"
|
|
||||||
#include "scheduler/scheduler.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
const limine_file& GetInitProgram() {
|
|
||||||
const limine_module_response& resp = boot::GetModules();
|
|
||||||
dbgln("Dumping modules");
|
|
||||||
for (uint64_t i = 0; i < resp.module_count; i++) {
|
|
||||||
const limine_file& file = *resp.modules[i];
|
|
||||||
dbgln("%s,%m,%x", file.path, file.address, file.size);
|
|
||||||
// TODO eventually compare this file path.
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
panic("No init program found");
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void LoadInitProgram() {
|
|
||||||
const limine_file& init_prog = GetInitProgram();
|
|
||||||
|
|
||||||
sched::InsertProcess(
|
|
||||||
new Process(reinterpret_cast<uint64_t>(init_prog.address)));
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
void LoadInitProgram();
|
|
||||||
|
|
@ -25,14 +25,14 @@ Process* Process::RootProcess() {
|
||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
Process::Process(uint64_t elf_ptr) : id_(gNextId++) {
|
Process::Process() : id_(gNextId++) {
|
||||||
cr3_ = phys_mem::AllocatePage();
|
cr3_ = phys_mem::AllocatePage();
|
||||||
InitializePml4(cr3_);
|
InitializePml4(cr3_);
|
||||||
CreateThread(elf_ptr);
|
CreateThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Process::CreateThread(uint64_t elf_ptr) {
|
void Process::CreateThread() {
|
||||||
Thread* thread = new Thread(this, next_thread_id_++, elf_ptr);
|
Thread* thread = new Thread(this, next_thread_id_++);
|
||||||
ThreadEntry* tentry = new ThreadEntry{
|
ThreadEntry* tentry = new ThreadEntry{
|
||||||
.thread = thread,
|
.thread = thread,
|
||||||
.next = nullptr,
|
.next = nullptr,
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,12 @@ class Process {
|
||||||
public:
|
public:
|
||||||
// Caller takes ownership of returned process.
|
// Caller takes ownership of returned process.
|
||||||
static Process* RootProcess();
|
static Process* RootProcess();
|
||||||
Process(uint64_t elf_ptr);
|
Process();
|
||||||
|
|
||||||
uint64_t id() { return id_; }
|
uint64_t id() { return id_; }
|
||||||
uint64_t cr3() { return cr3_; }
|
uint64_t cr3() { return cr3_; }
|
||||||
|
|
||||||
void CreateThread(uint64_t elf_ptr);
|
void CreateThread();
|
||||||
Thread* GetThread(uint64_t tid);
|
Thread* GetThread(uint64_t tid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,6 @@ class Scheduler {
|
||||||
Process& CurrentProcess() { return current_thread_->process(); }
|
Process& CurrentProcess() { return current_thread_->process(); }
|
||||||
Thread& CurrentThread() { return *current_thread_; }
|
Thread& CurrentThread() { return *current_thread_; }
|
||||||
|
|
||||||
void InsertProcess(Process* process) { proc_list_.InsertProcess(process); }
|
|
||||||
void Enqueue(Thread* thread) {
|
void Enqueue(Thread* thread) {
|
||||||
Thread* back = current_thread_;
|
Thread* back = current_thread_;
|
||||||
while (back->next_thread_ != nullptr) {
|
while (back->next_thread_ != nullptr) {
|
||||||
|
|
@ -109,7 +108,6 @@ void EnableScheduler() { GetScheduler().Enable(); }
|
||||||
|
|
||||||
void Yield() { GetScheduler().Yield(); }
|
void Yield() { GetScheduler().Yield(); }
|
||||||
|
|
||||||
void InsertProcess(Process* process) { GetScheduler().InsertProcess(process); }
|
|
||||||
void EnqueueThread(Thread* thread) { GetScheduler().Enqueue(thread); }
|
void EnqueueThread(Thread* thread) { GetScheduler().Enqueue(thread); }
|
||||||
|
|
||||||
Process& CurrentProcess() { return GetScheduler().CurrentProcess(); }
|
Process& CurrentProcess() { return GetScheduler().CurrentProcess(); }
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
#include "scheduler/thread.h"
|
#include "scheduler/thread.h"
|
||||||
|
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
#include "loader/elf_loader.h"
|
|
||||||
#include "scheduler/process.h"
|
#include "scheduler/process.h"
|
||||||
#include "scheduler/scheduler.h"
|
#include "scheduler/scheduler.h"
|
||||||
|
|
||||||
|
|
@ -17,8 +16,7 @@ extern "C" void thread_init() {
|
||||||
|
|
||||||
Thread* Thread::RootThread(Process* root_proc) { return new Thread(root_proc); }
|
Thread* Thread::RootThread(Process* root_proc) { return new Thread(root_proc); }
|
||||||
|
|
||||||
Thread::Thread(Process* proc, uint64_t tid, uint64_t elf_ptr)
|
Thread::Thread(Process* proc, uint64_t tid) : process_(proc), id_(tid) {
|
||||||
: process_(proc), id_(tid), elf_ptr_(elf_ptr) {
|
|
||||||
uint64_t* stack = new uint64_t[512];
|
uint64_t* stack = new uint64_t[512];
|
||||||
uint64_t* stack_ptr = stack + 511;
|
uint64_t* stack_ptr = stack + 511;
|
||||||
// 0: rip
|
// 0: rip
|
||||||
|
|
@ -30,13 +28,11 @@ Thread::Thread(Process* proc, uint64_t tid, uint64_t elf_ptr)
|
||||||
// 16: cr3
|
// 16: cr3
|
||||||
*(stack_ptr - 16) = proc->cr3();
|
*(stack_ptr - 16) = proc->cr3();
|
||||||
rsp0_ = reinterpret_cast<uint64_t>(stack_ptr - 16);
|
rsp0_ = reinterpret_cast<uint64_t>(stack_ptr - 16);
|
||||||
rsp0_start_ = reinterpret_cast<uint64_t>(stack_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);
|
|
||||||
while (true) {
|
while (true) {
|
||||||
dbgln("[%u.%u]", pid(), id_);
|
dbgln("[%u.%u]", pid(), id_);
|
||||||
sched::Yield();
|
sched::Yield();
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ class Thread {
|
||||||
public:
|
public:
|
||||||
static Thread* RootThread(Process* root_proc);
|
static Thread* RootThread(Process* root_proc);
|
||||||
|
|
||||||
explicit Thread(Process* proc, uint64_t tid, uint64_t elf_ptr);
|
explicit Thread(Process* proc, uint64_t tid);
|
||||||
|
|
||||||
uint64_t tid() { return id_; };
|
uint64_t tid() { return id_; };
|
||||||
uint64_t pid();
|
uint64_t pid();
|
||||||
|
|
@ -17,7 +17,6 @@ class Thread {
|
||||||
Process& process() { return *process_; }
|
Process& process() { return *process_; }
|
||||||
|
|
||||||
uint64_t* Rsp0Ptr() { return &rsp0_; }
|
uint64_t* Rsp0Ptr() { return &rsp0_; }
|
||||||
uint64_t Rsp0Start() { return rsp0_start_; }
|
|
||||||
|
|
||||||
// Called the first time the thread starts up.
|
// Called the first time the thread starts up.
|
||||||
void Init();
|
void Init();
|
||||||
|
|
@ -31,12 +30,7 @@ class Thread {
|
||||||
Process* process_;
|
Process* process_;
|
||||||
uint64_t id_;
|
uint64_t id_;
|
||||||
|
|
||||||
uint64_t elf_ptr_;
|
|
||||||
|
|
||||||
// Stack pointer to take on resume.
|
// Stack pointer to take on resume.
|
||||||
// Stack will contain the full thread context.
|
// Stack will contain the full thread context.
|
||||||
uint64_t rsp0_;
|
uint64_t rsp0_;
|
||||||
// Stack pointer to take when returning from userspace.
|
|
||||||
// I don't think me mind clobbering the stack here.
|
|
||||||
uint64_t rsp0_start_;
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
#include "syscall/syscall.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "debug/debug.h"
|
|
||||||
#include "scheduler/scheduler.h"
|
|
||||||
|
|
||||||
#define EFER 0xC0000080
|
|
||||||
#define STAR 0xC0000081
|
|
||||||
#define LSTAR 0xC0000082
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
uint64_t GetMSR(uint32_t msr) {
|
|
||||||
uint32_t lo, hi;
|
|
||||||
asm("rdmsr" : "=a"(lo), "=d"(hi) : "c"(msr));
|
|
||||||
return (static_cast<uint64_t>(hi) << 32) | lo;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetMSR(uint32_t msr, uint64_t val) {
|
|
||||||
uint32_t lo = static_cast<uint32_t>(val);
|
|
||||||
uint32_t hi = val >> 32;
|
|
||||||
asm("wrmsr" ::"a"(lo), "d"(hi), "c"(msr));
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void syscall_enter();
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// Used by syscall_enter.s
|
|
||||||
extern "C" uint64_t GetKernelRsp() {
|
|
||||||
return sched::CurrentThread().Rsp0Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitSyscall() {
|
|
||||||
uint64_t efer_val = GetMSR(EFER);
|
|
||||||
efer_val |= 1;
|
|
||||||
SetMSR(EFER, efer_val);
|
|
||||||
if (GetMSR(EFER) != efer_val) {
|
|
||||||
panic("Failed to set EFER MSR");
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t star_val = GetMSR(STAR);
|
|
||||||
// FIXME: Fix GDT such that we can properly set the user CS.
|
|
||||||
// Due to the ability to jump from a 64 bit kernel into compatibility mode,
|
|
||||||
// we set the user_cs to the kernel_cs because it adds 16 to jump to 64-bit
|
|
||||||
// mode. See AMD Manual 3.4 instruction SYSRET for more info.
|
|
||||||
uint64_t kernel_cs = 0x8;
|
|
||||||
uint64_t user_cs = kernel_cs;
|
|
||||||
star_val |= (kernel_cs << 32) | (user_cs << 48);
|
|
||||||
SetMSR(STAR, star_val);
|
|
||||||
SetMSR(LSTAR, reinterpret_cast<uint64_t>(syscall_enter));
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void SyscallHandler(uint64_t call_id, char* message) {
|
|
||||||
dbgln(message);
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
void InitSyscall();
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
.global syscall_enter
|
|
||||||
syscall_enter:
|
|
||||||
# Technically don't need to save all of these as
|
|
||||||
# the SYS V ABI will preserve some of them by
|
|
||||||
# default but I doubt that this costs us much.
|
|
||||||
push %rbx
|
|
||||||
push %rcx # Special! This is the return address
|
|
||||||
push %rdx
|
|
||||||
push %rsi
|
|
||||||
push %rdi
|
|
||||||
push %r8
|
|
||||||
push %r9
|
|
||||||
push %r10
|
|
||||||
push %r11
|
|
||||||
push %r12
|
|
||||||
push %r13
|
|
||||||
push %r14
|
|
||||||
push %r15
|
|
||||||
|
|
||||||
call GetKernelRsp
|
|
||||||
|
|
||||||
# RAX holds the kernel RSP now.
|
|
||||||
mov %rsp, %rbx
|
|
||||||
mov %rax, %rsp
|
|
||||||
push %rbx
|
|
||||||
|
|
||||||
# Now that we are on the kernel stack we can re-enable interrupts.
|
|
||||||
sti
|
|
||||||
|
|
||||||
# Restore caller registers using the userspace rsp in rbx
|
|
||||||
mov 0x40(%rbx), %rdi
|
|
||||||
mov 0x48(%rbx), %rsi
|
|
||||||
mov 0x50(%rbx), %rdx
|
|
||||||
mov 0x58(%rbx), %rcx
|
|
||||||
# Don't push the rbp and rsp as the callee will do so.
|
|
||||||
call SyscallHandler
|
|
||||||
|
|
||||||
# Clear interrupts since we are moving back to the user stack here.
|
|
||||||
# The sysret call will re-enable them for us.
|
|
||||||
cli
|
|
||||||
|
|
||||||
# Pop the userspace rsp off the stack
|
|
||||||
pop %rsp
|
|
||||||
|
|
||||||
pop %r15
|
|
||||||
pop %r14
|
|
||||||
pop %r13
|
|
||||||
pop %r12
|
|
||||||
pop %r11 # Contains rflags.
|
|
||||||
pop %r10
|
|
||||||
pop %r9
|
|
||||||
pop %r8
|
|
||||||
pop %rdi
|
|
||||||
pop %rsi
|
|
||||||
pop %rdx
|
|
||||||
pop %rcx # Contains return address.
|
|
||||||
pop %rbx
|
|
||||||
# Because we haven't touched rax since calling syscall_handler it should still have the return value.
|
|
||||||
sysretq
|
|
||||||
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
.text
|
|
||||||
|
|
||||||
.global _start
|
|
||||||
_start:
|
|
||||||
call main
|
|
||||||
call _exit
|
|
||||||
|
|
||||||
_exit:
|
|
||||||
mov $1, %rdi
|
|
||||||
syscall
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
#include "include/zcall.h"
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
uint64_t SysCall1(uint64_t number, const void* first) {
|
|
||||||
uint64_t return_code;
|
|
||||||
asm("syscall" : "=a"(return_code) : "D"(number), "S"(first) : "rcx", "r11");
|
|
||||||
return return_code;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t ZDebug(const char* message) {
|
|
||||||
return SysCall1(Z_DEBUG_PRINT, message);
|
|
||||||
}
|
|
||||||
|
|
@ -3,12 +3,10 @@
|
||||||
#include "common/gdt.h"
|
#include "common/gdt.h"
|
||||||
#include "debug/debug.h"
|
#include "debug/debug.h"
|
||||||
#include "interrupt/interrupt.h"
|
#include "interrupt/interrupt.h"
|
||||||
#include "loader/init_loader.h"
|
|
||||||
#include "memory/kernel_heap.h"
|
#include "memory/kernel_heap.h"
|
||||||
#include "memory/paging_util.h"
|
#include "memory/paging_util.h"
|
||||||
#include "memory/physical_memory.h"
|
#include "memory/physical_memory.h"
|
||||||
#include "scheduler/scheduler.h"
|
#include "scheduler/scheduler.h"
|
||||||
#include "syscall/syscall.h"
|
|
||||||
|
|
||||||
extern "C" void zion() {
|
extern "C" void zion() {
|
||||||
InitGdt();
|
InitGdt();
|
||||||
|
|
@ -19,12 +17,12 @@ extern "C" void zion() {
|
||||||
KernelHeap heap(0xFFFFFFFF'40000000, 0xFFFFFFFF'80000000);
|
KernelHeap heap(0xFFFFFFFF'40000000, 0xFFFFFFFF'80000000);
|
||||||
phys_mem::InitPhysicalMemoryManager();
|
phys_mem::InitPhysicalMemoryManager();
|
||||||
|
|
||||||
InitSyscall();
|
|
||||||
|
|
||||||
sched::InitScheduler();
|
sched::InitScheduler();
|
||||||
|
Process p1;
|
||||||
|
p1.CreateThread();
|
||||||
|
Process p2;
|
||||||
|
p2.CreateThread();
|
||||||
sched::EnableScheduler();
|
sched::EnableScheduler();
|
||||||
|
|
||||||
LoadInitProgram();
|
|
||||||
sched::Yield();
|
sched::Yield();
|
||||||
|
|
||||||
dbgln("Sleeping!");
|
dbgln("Sleeping!");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue