reorg: split the runtime into library/kernel concern modules (C1)

The one giant `runtime` module (with a `system.zig` that was itself a dumping
ground of unrelated syscalls) is split into directly-importable, flat concern
modules under library/kernel/:

  system-call  ipc  memory  process  thread  time  logging  file-system  service  start
  (+ the device/service clients: device, device-manager, block, display, input)

system.zig is dissolved — its functions moved to their concern home (mmap ->
memory, spawn/kill/exit -> process, sleep/clock -> time, write/klog -> logging,
fs* -> file-system). `memory` merges heap+dma+shared-memory behind one flat API
(memory.allocator/dmaAlloc/sharedCreate/mmap), keeping heap's state and malloc
export single. The memory<->thread dependency cycle (heap needs Thread.Mutex,
thread needs mmap) is broken by having thread allocate its own stack via the raw
mmap syscall, so the module graph is a DAG.

This is the atomic step: all 42 internal cross-imports flip from relative to
module imports at once. `runtime.zig` and `system.zig` become thin re-export
SHIMS so the ~38 consumers keep compiling on `runtime.*` untouched; they migrate
to direct imports in C2, after which the shims are deleted (C5).

zig build + zig build test green; 14 QEMU cases pass (smoke, process,
process-kill, thread-spawn/join, logger, vfs, fat-mount, display-native,
usb-storage, virtio-gpu, device-manager, input, power-button).
This commit is contained in:
Daniel Samson
2026-07-22 22:53:13 +01:00
parent 3e69712b97
commit 60f32ee9ff
21 changed files with 636 additions and 467 deletions
+44 -67
View File
@@ -1,74 +1,51 @@
//! danos user-space runtime library — a nascent libc. Every user binary (init,
//! and later the VFS server + device drivers) imports this as `@import("runtime")`:
//! system_call wrappers, the C-convention heap, IPC helpers, and the process start
//! shim. It is compiled into each binary (inheriting its `.large` code model and
//! freestanding target), so all user programs share one implementation.
//! runtime.zig — a **compatibility shim** for the runtime split (reorg C1–C5).
//!
//! A user binary only defines a `pub fn main() void` or
//! `pub fn main(init: runtime.process.Init) void` (arguments arrive via `init`).
//! The panic handler and the `_start` entry pull live in the shared compilation
//! root, library/runtime/root.zig, which build.zig wires around every program —
//! nothing to declare per source file.
//! `library/runtime` became `library/kernel`, and the one giant `runtime` module is being
//! split into directly-importable concern modules (`ipc`, `memory`, `process`, `time`,
//! `logging`, `file-system`, `service`, `thread`, `start`, plus the device/service clients).
//! This file re-exports those modules under the old `runtime.*` names so the ~38 consumers
//! keep compiling until each is migrated to direct imports. Deleted in step C5.
pub const system = @import("system.zig");
pub const log = @import("log.zig");
/// Monotonic time, delays, and deadlines over the kernel clock/sleep/timer syscalls
/// — an `Instant`/`Duration` front door, no time service (docs/timers.md).
pub const time = @import("time.zig");
pub const heap = @import("heap.zig");
pub const ipc = @import("ipc.zig");
pub const start = @import("start.zig");
/// Client for talking to the device manager (the hello handshake a supervised
/// driver owes at startup). See library/runtime/device-manager.zig. The wire
/// protocol itself is the library/protocol/device-manager module, imported
/// directly by drivers and services that speak it.
pub const device_manager = @import("device-manager.zig");
/// Keyboard-event listening (subscribe/next) and broadcasting (publish), over the input
/// service. See library/runtime/input.zig and system/services/input/.
pub const input = @import("input.zig");
/// POSIX-style file API: open/read/write/lseek/stat/close.
/// C stdio: fopen/fread/fwrite/fseek/ftell/fclose over unistd.
/// Device access for drivers: enumerate/claim/mmioMap.
pub const device = @import("device.zig");
/// DMA-capable memory for drivers: contiguous, pinned, uncacheable buffers.
pub const dma = @import("dma.zig");
/// Shared cacheable memory: create a region + capability, pass the capability to another
/// process (an `ipc_call` send_cap), map the same pages there. See library/runtime/shared-memory.zig
/// and docs/display-v2.md.
pub const shared_memory = @import("shared-memory.zig");
// The USB class-driver client moved to its domain home, library/device/usb (module
// "usb"): it is bus-family logic, not core runtime, and re-exporting it here compiled it
// into every binary. USB class drivers import it directly with @import("usb").
/// Block-device client: read/write a block device (a USB stick, via
/// usb-storage). See library/runtime/block.zig.
pub const block = @import("block.zig");
/// Display-service client: query the mode, and (from D3) create layers, draw, and
/// present frames. See library/runtime/display.zig and system/services/display/.
pub const display = @import("display.zig");
/// The danos-native file API (open/read/write/list over the user-space VFS) — the
/// layer danos programs use directly, and where the operations that later become
/// `std.os.danos` are staged. See docs/zig-self-hosting.md.
pub const fs = @import("fs.zig");
/// Re-exported so the root shim (root.zig) can install it as the panic handler.
pub const system = @import("system"); // the system.zig compatibility shim
pub const ipc = @import("ipc");
pub const memory = @import("memory");
pub const allocator = memory.allocator;
pub const process = @import("process");
pub const service = @import("service");
pub const Thread = @import("thread").Thread;
pub const time = @import("time");
pub const log = @import("logging");
pub const logging = @import("logging");
pub const fs = @import("file-system");
pub const start = @import("start");
pub const panic = start.panic;
/// Process entry types: the `Init` handed to `main`, and its `Arguments`.
pub const process = @import("process.zig");
// Device / service clients (relocated to library/device and library/client in C3/C4).
pub const device = @import("device");
pub const device_manager = @import("device-manager");
pub const input = @import("input");
pub const block = @import("block");
pub const display = @import("display");
/// Threads: `runtime.Thread`, std.Thread-shaped, over the private thread ABI
/// (docs/threading.md). A binary must be built multi-threaded to spawn.
pub const Thread = @import("thread.zig").Thread;
/// The heap as a namespace (`runtime.heap.allocator()`), plus `runtime.allocator`.
pub const heap = struct {
pub const allocator = memory.allocator;
};
/// The service harness: one replyWait loop folding requests, signals, and
/// notifications into callbacks (docs/process-lifecycle.md).
pub const service = @import("service.zig");
/// `runtime.dma.*` mapped onto the flat `memory` API (memory groups heap+dma+shared-memory).
pub const dma = struct {
pub const Region = memory.DmaRegion;
pub const coherent = memory.dma_coherent;
pub const write_combining = memory.dma_write_combining;
pub const below_4g = memory.dma_below_4g;
pub const alloc = memory.dmaAlloc;
pub const free = memory.dmaFree;
};
/// The heap as a `std.mem.Allocator`, for Zig `std` containers in user code.
pub const allocator = heap.allocator;
/// `runtime.shared_memory.*` mapped onto the flat `memory` API.
pub const shared_memory = struct {
pub const Region = memory.SharedRegion;
pub const create = memory.sharedCreate;
pub const map = memory.sharedMap;
pub const physical = memory.sharedPhysical;
};