M9: user-space VFS server + client file API (open/read/write/stat + stdio)

The payoff milestone: files are served by a user-space process, reached over
IPC — the kernel never sees a path or an fd.

- lib/vfs_proto.zig: the VFS wire protocol (Op, Request/Reply fixed header +
  inline payload, Stat), shared by client and server; one message <= MSG_MAX.
- lib/ipc.zig: replyWait() — the server-side dual-return stub (length in rax,
  badge in rdx via a "+{rdx}" read-write operand), deferred from M7.
- sbin/vfs.zig: the real VFS server — an in-heap ramfs (open creates a node)
  with an IPC_ReplyWait dispatch loop serving open/read/write/stat/close.
  Registers its endpoint under the well-known vfs id at startup.
- lib/unistd.zig: POSIX-style client API in rt — a per-process fd table +
  open/close/read/write/lseek/stat, each an IPC_Call to the VFS. The kernel
  knows nothing of fds; the table lives here.
- lib/stdio.zig: C stdio over unistd — FILE + fopen/fclose/fread/fwrite/
  fseek/ftell/rewind/feof/ferror/fputs/fputc/fgetc (unbuffered for now).
- sbin/vfstest.zig: a client that opens/writes/seeks/reads a file and only
  heartbeats "vfstest: ok" if the round trip matched. Packed in the initrd.
- New `vfs` test drives it end to end. initrd test relaxed to generic
  liveness. Suite 31/31.
This commit is contained in:
Daniel Samson
2026-07-09 07:48:24 +01:00
parent 750a73f050
commit b0f894f50c
10 changed files with 583 additions and 14 deletions
+3
View File
@@ -218,6 +218,7 @@ pub fn build(b: *std.Build) void {
// the host-side mkinitrd tool. The bootloader ferries the image to the kernel,
// which unpacks it and spawns each program (src/user/proto/initrd.zig).
const vfs_exe = addUserBinary(b, kernel_target, rt_mod, "vfs", "sbin/vfs.zig");
const vfstest_exe = addUserBinary(b, kernel_target, rt_mod, "vfstest", "sbin/vfstest.zig");
// Pack the user binaries into the initrd image with the host-side Python tool
// (the container format is trivial, and Python sidesteps std API churn). Args:
@@ -227,6 +228,8 @@ pub fn build(b: *std.Build) void {
const initrd_img = mk_run.addOutputFileArg("initrd.img");
mk_run.addArg("vfs");
mk_run.addFileArg(vfs_exe.getEmittedBin());
mk_run.addArg("vfstest");
mk_run.addFileArg(vfstest_exe.getEmittedBin());
// Install the image to zig-out/bin (so the QEMU test harness picks it up like
// the other binaries). The run-x86-64 ESP install is added below.