hachem.wtf
aboutsummaryrefslogtreecommitdiff
path: root/boot/user.zig
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-10-04 16:03:42 +0200
committerhachem <im@hachem.wtf>2026-10-04 16:03:42 +0200
commit52dab7fc85d877e80e3032f0afabae906adebad8 (patch)
treeb6d56299b839413bb77b1b8c8fa9f7a682124a05 /boot/user.zig
parenta8a35a00a3c3c57cfbef2311d0348376c2e83208 (diff)
feat: fs tree and free list alloc
Diffstat (limited to 'boot/user.zig')
-rw-r--r--boot/user.zig18
1 files changed, 11 insertions, 7 deletions
diff --git a/boot/user.zig b/boot/user.zig
index 5ba6604..9bce9e9 100644
--- a/boot/user.zig
+++ b/boot/user.zig
@@ -8,8 +8,7 @@ const regs = @import("regs.zig");
const bridge = @import("bridge");
const Frame = regs.Frame;
-// scratch for a filename copied out of the caller. one static buffer is fine,
-// syscalls run one at a time (if=0)
+// scratch for a filename copied out of the caller legit one static buffer is fine
var name_buf: [64]u8 = undefined;
fn userName(ptr: u64) []const u8 {
const p: [*]const u8 = @ptrFromInt(ptr);
@@ -18,9 +17,6 @@ fn userName(ptr: u64) []const u8 {
return name_buf[0..i];
}
-// what the syscall stub leaves on the stack: the gp regs it pushed, then the
-// frame the cpu pushed on int 0x80. rax holds the syscall number in, and the
-// handler writes the return value back into it (restored by the stubs pop)
pub const SyscallFrame = extern struct {
r15: u64,
r14: u64,
@@ -49,8 +45,10 @@ pub fn installSyscall() void {
idt.setGate(0x80, @intFromPtr(&syscallStub), 3, 1); // ist1: big stack for vm calls
}
-// save gp regs, hand the frame to the zig handler, restore, iretq. the handler
-// returns via syscallframe.rax (restored by the pop below), exit() never returns
+// 1- save gp regs
+// 2- hand the frame to the zig handler
+// 3- restore
+// 4- iretq
export fn syscallStub() callconv(.naked) void {
asm volatile (regs.PUSH_GPRS ++
\\
@@ -120,6 +118,12 @@ export fn syscallHandler(frame: *SyscallFrame) callconv(.c) void {
const dst: [*]u8 = @ptrFromInt(frame.rdx);
frame.rax = bridge.fsReadInto(name, frame.rsi, dst[0..len]);
},
+ 6 => { // fs_write(name_ptr, buf_ptr, len): returns 1 ok / 0 fail
+ const len = @min(frame.rdx, 64 * 1024);
+ const name = userName(frame.rdi);
+ const src: [*]const u8 = @ptrFromInt(frame.rsi);
+ frame.rax = if (bridge.fsStore(name, src[0..len])) 1 else 0;
+ },
else => serial.write("[syscall] unknown\r\n"),
}
}