isolation M1: ring 3 + a real /sbin/init, end to end

Ring 3 works: user GDT descriptors (sysret-ready layout), TSS.rsp0,
U/S-bit user mappings (W^X preserved), an int 0x80 syscall gate with a
mutable trap frame, and a setjmp-style enter/exit path. /sbin/init is a
real freestanding Zig binary built from sbin/, shipped on the ESP,
loaded by the bootloader (BootInfo.init_base/len), validated and mapped
by an in-kernel user-ELF loader, and run at CPL 3 — syscalls: exit,
ping, write. Tests: user, user-pf (U/S isolation proof, error code
0x5), init. Suite 27/27.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Daniel Samson
2026-07-08 22:15:07 +01:00
co-authored by Claude Fable 5
parent 7501bd1703
commit 546dd44a2a
17 changed files with 838 additions and 25 deletions
+20 -1
View File
@@ -7,6 +7,7 @@ const log = @import("log.zig");
const pmm = @import("pmm.zig");
const heap = @import("heap.zig");
const scheduler = @import("scheduler.zig");
const usermode = @import("usermode.zig");
const platform = @import("platform");
const tests = @import("tests.zig");
const build_options = @import("build_options");
@@ -245,7 +246,25 @@ fn kmain(boot_info: *const BootInfo) noreturn {
log.checkpoint(cp_running);
status("kernel initialised.\n");
// TODO: init process
// Hand over to user space: run /sbin/init (read off the boot volume by the
// loader) in ring 3. Preemption is off for the run — the M1 user-mode path
// publishes *this* core's TSS.rsp0 and must not migrate (the flag is
// global, so the system goes cooperative meanwhile; the other cores are
// idle). init becomes a real schedulable process in M3.
if (boot_info.init_len != 0) {
status("starting /sbin/init...\n");
const image = @as([*]const u8, @ptrFromInt(boot_info.init_base))[0..boot_info.init_len];
scheduler.setPreemption(false);
const code = usermode.runInitElf(image);
scheduler.setPreemption(true);
if (code) |c| {
statusPrint("/sbin/init exited with code {d}.\n", .{c});
} else |err| {
statusPrint("/sbin/init failed to load: {s}\n", .{@errorName(err)});
}
} else {
status("no /sbin/init on the boot volume.\n");
}
status("\nnothing left to do; halting CPU.\n");