Update stale /sbin/ references to real FHS paths

The reorg moved user binaries under /system (init -> /system/services/init,
drivers -> /system/drivers/<name>, vfs-test -> /system/services/vfs/vfs-test), but
many comments and log strings still named the old /sbin/ home. Retarget them all:
kernel/loader/test comments and the two boot log lines, plus vision.md and the
driver-model.md proposed tree (also dropped the stale `d` suffixes and rt->runtime
there). The initial-ramdisk spawn log no longer fakes a /sbin/ prefix, since those
binaries live in different homes (services vs drivers).

Left the FSH design doc's /sbin and /lib rows alone — whether /sbin stays a
directory at all is a design call for its owner, not a stale-comment fix.
This commit is contained in:
Daniel Samson
2026-07-10 18:13:24 +01:00
parent be81394be3
commit b61b7775b9
12 changed files with 38 additions and 38 deletions
+1 -1
View File
@@ -142,7 +142,7 @@ pub const BootInformation = extern struct {
/// A device-tree boot path leaves this 0 and (later) fills a `device_tree_blob`
/// field instead, so the kernel discovers devices without knowing what booted it.
acpi_rsdp: u64 = 0,
/// The raw `/sbin/init` ELF image, read off the boot volume by the loader
/// The raw `/system/services/init` ELF image, read off the boot volume by the loader
/// into memory that survives the handoff (classified reserved, so the kernel
/// identity-maps it and never allocates over it). 0/0 = no init found — the
/// kernel boots without user space. Grows into a full initial_ramdisk handoff later.
+1 -1
View File
@@ -1,4 +1,4 @@
//! /sbin/bus — a user-space **bus driver**, and the smallest honest example of one.
//! /system/drivers/bus — a user-space **bus driver**, and the smallest honest example of one.
//!
//! A bus driver owns a device that *contains other devices*, enumerates them by some
//! bus-specific protocol, and publishes each one into the kernel's device table so a
+1 -1
View File
@@ -1,4 +1,4 @@
//! /sbin/hpet — a user-space HPET driver. It proves the whole driver model end to
//! /system/drivers/hpet — a user-space HPET driver. It proves the whole driver model end to
//! end: enumerate the device table, find the HPET, claim it, map its registers into
//! this ring-3 address space (strong-uncacheable), **bind its interrupt to an IPC
//! endpoint**, then sit blocked in `replyWait` until the hardware wakes it.
+6 -6
View File
@@ -272,18 +272,18 @@ fn kmain(boot_information: *const BootInformation) noreturn {
log.checkpoint(cp_running);
status("kernel initialised.\n");
// Hand over to user space: load /sbin/init (read off the boot volume by the
// Hand over to user space: load /system/services/init (read off the boot volume by the
// loader) and spawn it as a real ring-3 process, PID 1. It runs on its own
// address space, preemptively, alongside the kernel — no cooperative
// borrowing. This boot context then becomes the BSP's idle loop.
if (boot_information.init_len != 0) {
status("starting /sbin/init...\n");
status("starting /system/services/init...\n");
const image = @as([*]const u8, @ptrFromInt(boot_handoff.physicalToVirtual(boot_information.init_base)))[0..boot_information.init_len];
process.spawnProcess(image, 4) catch |err| {
statusPrint("/sbin/init failed to load: {s}\n", .{@errorName(err)});
statusPrint("/system/services/init failed to load: {s}\n", .{@errorName(err)});
};
} else {
status("no /sbin/init on the boot volume.\n");
status("no /system/services/init on the boot volume.\n");
}
// Spawn the extra user binaries the loader ferried in the initial_ramdisk (the VFS
@@ -294,7 +294,7 @@ fn kmain(boot_information: *const BootInformation) noreturn {
// Become the idle task: drop below every real task and halt until an
// interrupt. The timer keeps preempting into init and any other work.
scheduler.setPriority(0);
status("\nkernel idle; /sbin/init is running.\n");
status("\nkernel idle; /system/services/init is running.\n");
architecture.halt();
}
@@ -311,7 +311,7 @@ fn startInitialRamdiskBinaries(boot_information: *const boot_handoff.BootInforma
var i: u32 = 0;
while (i < rd.count) : (i += 1) {
const item = rd.entry(i) orelse continue;
statusPrint("starting /sbin/{s} (from initial_ramdisk)...\n", .{item.name});
statusPrint("starting {s} (from initial-ramdisk)...\n", .{item.name});
process.spawnProcess(item.blob, 4) catch |err| {
statusPrint("initial_ramdisk: {s} failed to load: {s}\n", .{ item.name, @errorName(err) });
};
+2 -2
View File
@@ -3,7 +3,7 @@
//! loader; in-kernel code is linked into the kernel image, not loaded here.
//!
//! Two entry points:
//! - `spawnProcess` loads a user ELF (`/sbin/init`, and later servers/drivers)
//! - `spawnProcess` loads a user ELF (`/system/services/init`, and later servers/drivers)
//! into a fresh address space and schedules it as a real preemptive ring-3
//! process on its own page tables. This is the production path.
//! - `run` executes a raw code blob (the user-pf isolation test program) on the
@@ -448,7 +448,7 @@ pub fn run(blob: []const u8) RunError!void {
pmm.free(stack_frame);
}
// --- user ELF loading (/sbin/init) ------------------------------------------
// --- user ELF loading (/system/services/init) ------------------------------------------
pub const InitError = error{
BadElf, // malformed/inapplicable image (magic, class, machine, type, bounds)
+4 -4
View File
@@ -868,7 +868,7 @@ fn procWorker() void {
scheduler.exit();
}
/// Real processes: load /sbin/init as TWO scheduled ring-3 processes, each with
/// Real processes: load /system/services/init as TWO scheduled ring-3 processes, each with
/// its own address space at the same virtual addresses, running concurrently
/// with a kernel task. Both must make heartbeat syscalls from CPL 3 — which can
/// only happen if each runs on its own page tables (CR3 switched correctly per
@@ -876,7 +876,7 @@ fn procWorker() void {
/// strongest cheap proof of address-space isolation.
fn processTest(boot_information: *const BootInformation) void {
log("DANOS-TEST-BEGIN: process\n", .{});
check("bootloader handed over sbin/init", boot_information.init_len != 0);
check("bootloader handed over /system/services/init", boot_information.init_len != 0);
if (boot_information.init_len == 0) {
result();
return;
@@ -920,14 +920,14 @@ fn userPfTest() void {
log("DANOS-TEST-RESULT: FAIL (user read of kernel memory did not fault)\n", .{});
}
/// The full PID-1 path: the bootloader read sbin/init off the boot volume and
/// The full PID-1 path: the bootloader read /system/services/init off the boot volume and
/// handed it over; load it as a user ELF and spawn it as a real ring-3 process
/// — the same call the normal boot path makes — then confirm it beats. init
/// heartbeats forever, so this proves it reaches ring 3, makes repeated syscalls
/// (write + sleep), and stays alive rather than exiting.
fn initTest(boot_information: *const BootInformation) void {
log("DANOS-TEST-BEGIN: init\n", .{});
check("bootloader handed over sbin/init", boot_information.init_len != 0);
check("bootloader handed over /system/services/init", boot_information.init_len != 0);
if (boot_information.init_len == 0) {
result();
return;
+2 -2
View File
@@ -1,5 +1,5 @@
//! /sbin/init — the first user-space program, PID 1. Built as its own
//! freestanding binary (see build.zig), shipped on the boot volume at sbin/init,
//! /system/services/init — the first user-space program, PID 1. Built as its own
//! freestanding binary (see build.zig), shipped on the boot volume at /system/services/init,
//! loaded by the bootloader, and started in ring 3 as a scheduled process by the
//! kernel (system/kernel/process.zig). It links against the shared user runtime
//! library `runtime` and talks to the kernel only through `runtime`'s system_call wrappers.
+1 -1
View File
@@ -1,4 +1,4 @@
//! /sbin/vfstest — a client that proves the VFS round trip end to end: open a
//! /system/services/vfs/vfs-test — a client that proves the VFS round trip end to end: open a
//! file through the `runtime` file API, write to it, seek back, read it, and compare.
//! On success it heartbeats "vfstest: ok" so the kernel test can observe it;
//! on failure it reports what went wrong. Shipped in the initial_ramdisk alongside vfs.