From 8e03bfc320686b3b74ea84b7f9be417a0e16b3a3 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Thu, 27 Aug 2026 09:48:38 +0200 Subject: [PATCH] feat(kernel): add int 0x80 syscall dispatch table --- include/syscall.h | 19 +++++++ src/syscall.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 include/syscall.h create mode 100644 src/syscall.c diff --git a/include/syscall.h b/include/syscall.h new file mode 100644 index 0000000..5942c65 --- /dev/null +++ b/include/syscall.h @@ -0,0 +1,19 @@ +#ifndef FROSTBYTE_SYSCALL_H +#define FROSTBYTE_SYSCALL_H + +#define sysExit 0 +#define sysWrite 1 +#define sysRead 2 +#define sysYield 3 +#define sysGetpid 4 +#define sysSbrk 5 +#define sysSleep 6 +#define sysOpen 7 +#define sysClose 8 +#define sysLseek 9 +#define sysStat 10 +#define sysGetdents 11 +#define sysMkdir 12 +#define sysUnlink 13 + +#endif diff --git a/src/syscall.c b/src/syscall.c new file mode 100644 index 0000000..16847e9 --- /dev/null +++ b/src/syscall.c @@ -0,0 +1,129 @@ +#include "syscall.h" +#include "isr.h" +#include "console.h" +#include "sched.h" +#include "vfs.h" +#include "fs.h" +#include "string.h" + +#define userSpaceMin 0x0000000040000000ull +#define userSpaceMax 0x0000800000000000ull + +static bool userRangeOk(uint64 pointer, uint64 length) +{ + if (pointer < userSpaceMin) + return false; + if (pointer + length < pointer) + return false; + if (pointer + length > userSpaceMax) + return false; + return true; +} + +static bool copyUserPath(uint64 pointer, char* dst, uint64 max) +{ + if (pointer < userSpaceMin || pointer >= userSpaceMax) + return false; + const char* src = (const char*)pointer; + for (uint64 i = 0; i < max; i++) { + dst[i] = src[i]; + if (src[i] == 0) + return true; + } + dst[max - 1] = 0; + return true; +} + +static int64 doWrite(uint64 fd, uint64 buffer, uint64 length) +{ + if (!userRangeOk(buffer, length)) + return -1; + return vfsWrite((int)fd, (const void*)buffer, length); +} + +static int64 doRead(uint64 fd, uint64 buffer, uint64 length) +{ + if (!userRangeOk(buffer, length)) + return -1; + return vfsRead((int)fd, (void*)buffer, length); +} + +uint64 syscallDispatch(Registers* regs) +{ + switch (regs->rax) { + case sysWrite: + regs->rax = (uint64)doWrite(regs->rdi, regs->rsi, regs->rdx); + return (uint64)regs; + case sysRead: + regs->rax = (uint64)doRead(regs->rdi, regs->rsi, regs->rdx); + return (uint64)regs; + case sysGetpid: + regs->rax = currentThreadId(); + return (uint64)regs; + case sysSbrk: + regs->rax = currentThreadSbrk((int64)regs->rdi); + return (uint64)regs; + case sysYield: + regs->rax = 0; + return schedule((uint64)regs); + case sysSleep: + threadSleep(regs->rdi); + regs->rax = 0; + return schedule((uint64)regs); + case sysExit: + threadExit(regs->rdi); + return schedule((uint64)regs); + case sysOpen: { + char path[256]; + if (!copyUserPath(regs->rdi, path, sizeof(path))) + regs->rax = (uint64)-1; + else + regs->rax = (uint64)(int64)vfsOpen(path, (uint32)regs->rsi); + return (uint64)regs; + } + case sysClose: + regs->rax = (uint64)(int64)vfsClose((int)regs->rdi); + return (uint64)regs; + case sysLseek: + regs->rax = (uint64)vfsLseek((int)regs->rdi, (int64)regs->rsi, (int)regs->rdx); + return (uint64)regs; + case sysStat: { + char path[256]; + FbStat st; + if (copyUserPath(regs->rdi, path, sizeof(path)) && + userRangeOk(regs->rsi, sizeof(FbStat)) && + vfsStat(path, &st) == 0) { + memcpy((void*)regs->rsi, &st, sizeof(FbStat)); + regs->rax = 0; + } else { + regs->rax = (uint64)-1; + } + return (uint64)regs; + } + case sysGetdents: + if (!userRangeOk(regs->rsi, regs->rdx)) + regs->rax = (uint64)-1; + else + regs->rax = (uint64)vfsGetdents((int)regs->rdi, (void*)regs->rsi, regs->rdx); + return (uint64)regs; + case sysMkdir: { + char path[256]; + if (!copyUserPath(regs->rdi, path, sizeof(path))) + regs->rax = (uint64)-1; + else + regs->rax = (uint64)(int64)vfsMkdir(path); + return (uint64)regs; + } + case sysUnlink: { + char path[256]; + if (!copyUserPath(regs->rdi, path, sizeof(path))) + regs->rax = (uint64)-1; + else + regs->rax = (uint64)(int64)vfsUnlink(path); + return (uint64)regs; + } + default: + regs->rax = (uint64)-1; + return (uint64)regs; + } +}