C5: delete the runtime.zig and system.zig compatibility shims

With every consumer migrated (C2), nothing imports `runtime` or `system` any
longer. Removed both shim files and their build.zig module definitions, dropped
the `runtime` entry from `default_imports`, and rewrote the per-binary root shim
(library/kernel/root.zig) to import `start` (_start + panic) and `logging`
(std_options) directly instead of through `runtime`.

addUserBinary/addThreadedUserBinary/addUserBinaryImpl lose their `runtime_module`
parameter; the root module now pulls the two modules it needs out of
`default_imports` via a small findImport helper.

The runtime dumping ground is gone: the userspace library is library/kernel
(concern modules), library/device (driver/pci/usb/block/model/mmio/acpi data),
library/client (display, input service clients), and library/protocol (wire
contracts). Consumers @import concern modules by name.

Verified: zig build, zig build test, and QEMU (smoke, thread-spawn, thread-mutex,
logger, display-native, device-manager, usb-storage, input).
This commit is contained in:
Daniel Samson 2026-07-22 23:32:05 +01:00
parent 23bcd77c58
commit 37326c7664
No known key found for this signature in database
GPG Key ID: A9EB2589C60F7268
4 changed files with 60 additions and 202 deletions

122
build.zig
View File

@ -64,11 +64,10 @@ fn addUserBinary(
b: *std.Build,
target: std.Build.ResolvedTarget,
default_imports: []const std.Build.Module.Import,
runtime_module: *std.Build.Module,
name: []const u8,
root: []const u8,
) *std.Build.Step.Compile {
return addUserBinaryImpl(b, target, default_imports, runtime_module, name, root, false);
return addUserBinaryImpl(b, target, default_imports, name, root, false);
}
/// As `addUserBinary`, but built multi-threaded (`single_threaded = false`) so real
@ -78,28 +77,34 @@ fn addThreadedUserBinary(
b: *std.Build,
target: std.Build.ResolvedTarget,
default_imports: []const std.Build.Module.Import,
runtime_module: *std.Build.Module,
name: []const u8,
root: []const u8,
) *std.Build.Step.Compile {
return addUserBinaryImpl(b, target, default_imports, runtime_module, name, root, true);
return addUserBinaryImpl(b, target, default_imports, name, root, true);
}
/// The module registered under `name` in `imports` the root shim reaches the
/// couple of concern modules it needs (start, logging) out of the default set.
fn findImport(imports: []const std.Build.Module.Import, name: []const u8) *std.Build.Module {
for (imports) |import| {
if (std.mem.eql(u8, import.name, name)) return import.module;
}
@panic("default_imports is missing a module the root shim needs");
}
fn addUserBinaryImpl(
b: *std.Build,
target: std.Build.ResolvedTarget,
default_imports: []const std.Build.Module.Import,
runtime_module: *std.Build.Module,
name: []const u8,
root: []const u8,
threaded: bool,
) *std.Build.Step.Compile {
// Every user binary gets the same default set of importable modules the library/kernel
// concern modules (ipc, memory, process, time, logging, file-system, ...), the device/
// service clients (driver, block, display, input), mmio, acpi-ids, xkeyboard-config, and
// the compatibility `runtime` shim. Per-binary extras go through programModule(exe).addImport.
// Settings (target, optimize, code model, ...) live on the root module only; the program
// and runtime modules leave theirs null and inherit them.
// service clients (driver, block, display, input), mmio, acpi-ids, and xkeyboard-config.
// Per-binary extras go through programModule(exe).addImport. Settings (target, optimize,
// code model, ...) live on the root module only; the program module inherits them.
const program_module = b.createModule(.{
.root_source_file = b.path(root),
.imports = default_imports,
@ -115,8 +120,11 @@ fn addUserBinaryImpl(
.sanitize_c = .off,
.stack_check = false,
.stack_protector = false,
// The root shim itself imports only start (_start + panic) and logging
// (std_options); the program's own file reaches the full default set.
.imports = &.{
.{ .name = "runtime", .module = runtime_module },
.{ .name = "start", .module = findImport(default_imports, "start") },
.{ .name = "logging", .module = findImport(default_imports, "logging") },
.{ .name = "program", .module = program_module },
},
}),
@ -508,38 +516,6 @@ pub fn build(b: *std.Build) void {
.{ .name = "input-protocol", .module = input_protocol_module },
},
});
// system.zig compatibility shim for runtime.system.*, re-exporting the concern modules.
const system_module = b.addModule("system", .{
.root_source_file = b.path("library/kernel/system.zig"),
.imports = &.{
.{ .name = "memory", .module = memory_module },
.{ .name = "process", .module = process_module },
.{ .name = "time", .module = time_module },
.{ .name = "logging", .module = logging_module },
.{ .name = "file-system", .module = file_system_module },
},
});
// runtime.zig compatibility shim re-exporting every concern module under the old runtime.* names.
const runtime_module = b.addModule("runtime", .{
.root_source_file = b.path("library/kernel/runtime.zig"),
.imports = &.{
.{ .name = "system", .module = system_module },
.{ .name = "ipc", .module = ipc_module },
.{ .name = "memory", .module = memory_module },
.{ .name = "process", .module = process_module },
.{ .name = "service", .module = service_module },
.{ .name = "thread", .module = thread_module },
.{ .name = "time", .module = time_module },
.{ .name = "logging", .module = logging_module },
.{ .name = "file-system", .module = file_system_module },
.{ .name = "start", .module = start_module },
.{ .name = "driver", .module = driver_module },
.{ .name = "input", .module = input_client_module },
.{ .name = "block", .module = block_client_module },
.{ .name = "display", .module = display_client_module },
},
});
// A device driver's view of its claimed PCI function: config-space header fields, BAR
// decode + map, and the capability walk (library/device/pci/pci.zig). The generic PCI
// mechanics every leaf PCI driver used to re-derive inline. Imports the driver (device
@ -635,11 +611,9 @@ pub fn build(b: *std.Build) void {
// --- init: the first user-space program (a system service) ---
// The default module set every user binary can import directly: the library/kernel
// concern modules, the device/service clients, mmio, the keyboard layouts, the ACPI id
// registry, and the compatibility `runtime` shim (retired once every consumer has migrated
// off it in C2/C5). Per-binary extras are added with programModule(exe).addImport.
// concern modules, the device/service clients, mmio, the keyboard layouts, and the ACPI
// id registry. Per-binary extras are added with programModule(exe).addImport.
const default_imports = [_]std.Build.Module.Import{
.{ .name = "runtime", .module = runtime_module },
.{ .name = "mmio", .module = mmio_module },
.{ .name = "xkeyboard-config", .module = xkeyboard_config_module },
.{ .name = "acpi-ids", .module = acpi_ids_module },
@ -662,7 +636,7 @@ pub fn build(b: *std.Build) void {
// Built by the shared user-binary recipe (see addUserBinary): freestanding,
// linked into the kernel's user region against the library/kernel modules, and
// started in ring 3 by the kernel's user-ELF loader.
const init_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "init", "system/services/init/init.zig");
const init_exe = addUserBinary(b, kernel_target, &default_imports, "init", "system/services/init/init.zig");
programModule(init_exe).addImport("power-protocol", power_protocol_module);
// init reads the same `serial` flag the kernel does: its liveness heartbeat is a
// serial/test-build diagnostic (the QEMU harness's init tests assert on it, and
@ -678,13 +652,13 @@ pub fn build(b: *std.Build) void {
// Each is built by the same user-binary recipe and laid out at its FHS path on
// the boot volume (see `bundled` below). The EFI loader walks the tree at boot
// and hands the kernel an in-RAM initial_ramdisk of it (system/initial-ramdisk.zig).
const vfstest_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "vfs-test", "system/services/vfs-test/vfs-test.zig");
const ps2_bus_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "ps2-bus", "system/drivers/ps2-bus/ps2-bus.zig");
const ps2_keyboard_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "ps2-keyboard", "system/drivers/ps2-bus/keyboard.zig");
const vfstest_exe = addUserBinary(b, kernel_target, &default_imports, "vfs-test", "system/services/vfs-test/vfs-test.zig");
const ps2_bus_exe = addUserBinary(b, kernel_target, &default_imports, "ps2-bus", "system/drivers/ps2-bus/ps2-bus.zig");
const ps2_keyboard_exe = addUserBinary(b, kernel_target, &default_imports, "ps2-keyboard", "system/drivers/ps2-bus/keyboard.zig");
programModule(ps2_keyboard_exe).addImport("input-protocol", input_protocol_module);
const ps2_mouse_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "ps2-mouse", "system/drivers/ps2-bus/mouse.zig");
const ps2_mouse_exe = addUserBinary(b, kernel_target, &default_imports, "ps2-mouse", "system/drivers/ps2-bus/mouse.zig");
programModule(ps2_mouse_exe).addImport("input-protocol", input_protocol_module);
const usb_xhci_bus_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "usb-xhci-bus", "system/drivers/usb-xhci-bus/usb-xhci-bus.zig");
const usb_xhci_bus_exe = addUserBinary(b, kernel_target, &default_imports, "usb-xhci-bus", "system/drivers/usb-xhci-bus/usb-xhci-bus.zig");
programModule(usb_xhci_bus_exe).addImport("device-manager-protocol", device_manager_protocol_module);
// The xHCI bus driver builds chapter-9 requests and decodes descriptors from
// usb-abi, and reports each interface's (class,subclass,protocol) identity via
@ -695,46 +669,46 @@ pub fn build(b: *std.Build) void {
// The USB HID class drivers: keyboard and mouse. They own no hardware each
// opens its device through runtime.usb (the transfer protocol) and publishes to
// the input service. They build chapter-9 class requests from usb-abi.
const usb_hid_keyboard_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "usb-hid-keyboard", "system/drivers/usb-hid/keyboard.zig");
const usb_hid_keyboard_exe = addUserBinary(b, kernel_target, &default_imports, "usb-hid-keyboard", "system/drivers/usb-hid/keyboard.zig");
programModule(usb_hid_keyboard_exe).addImport("usb", usb_module);
programModule(usb_hid_keyboard_exe).addImport("usb-abi", usb_abi_module);
programModule(usb_hid_keyboard_exe).addImport("input-protocol", input_protocol_module);
const usb_hid_mouse_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "usb-hid-mouse", "system/drivers/usb-hid/mouse.zig");
const usb_hid_mouse_exe = addUserBinary(b, kernel_target, &default_imports, "usb-hid-mouse", "system/drivers/usb-hid/mouse.zig");
programModule(usb_hid_mouse_exe).addImport("usb", usb_module);
programModule(usb_hid_mouse_exe).addImport("usb-abi", usb_abi_module);
programModule(usb_hid_mouse_exe).addImport("input-protocol", input_protocol_module);
// The USB mass-storage class driver: opens its device via runtime.usb, drives it
// with Bulk-Only Transport + SCSI, and serves the block protocol under `.block`.
const usb_storage_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "usb-storage", "system/drivers/usb-storage/usb-storage.zig");
const usb_storage_exe = addUserBinary(b, kernel_target, &default_imports, "usb-storage", "system/drivers/usb-storage/usb-storage.zig");
programModule(usb_storage_exe).addImport("usb", usb_module);
programModule(usb_storage_exe).addImport("block-protocol", block_protocol_module);
// The FAT filesystem server: mounts the block device and serves it into the VFS
// at /mnt/usb. Its engine (engine.zig / on-disk.zig) is imported relatively.
const fat_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "fat", "system/services/fat/fat.zig");
const fat_exe = addUserBinary(b, kernel_target, &default_imports, "fat", "system/services/fat/fat.zig");
programModule(fat_exe).addImport("vfs-protocol", vfs_protocol_module);
// Threaded: the display runs a mouse-listener thread alongside its compositor loop
// (docs/threading.md, docs/display.md), so it opts into real atomics/TLS.
const display_exe = addThreadedUserBinary(b, kernel_target, &default_imports, runtime_module, "display", "system/services/display/display.zig");
const display_exe = addThreadedUserBinary(b, kernel_target, &default_imports, "display", "system/services/display/display.zig");
programModule(display_exe).addImport("display-protocol", display_protocol_module);
programModule(display_exe).addImport("scanout-protocol", scanout_protocol_module);
const display_demo_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "display-demo", "system/services/display-demo/display-demo.zig");
const virtio_gpu_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "virtio-gpu", "system/drivers/virtio-gpu/virtio-gpu.zig");
const display_demo_exe = addUserBinary(b, kernel_target, &default_imports, "display-demo", "system/services/display-demo/display-demo.zig");
const virtio_gpu_exe = addUserBinary(b, kernel_target, &default_imports, "virtio-gpu", "system/drivers/virtio-gpu/virtio-gpu.zig");
programModule(virtio_gpu_exe).addImport("pci", pci_module); // library/device/pci the claimed-function view
programModule(virtio_gpu_exe).addImport("display-protocol", display_protocol_module);
programModule(virtio_gpu_exe).addImport("scanout-protocol", scanout_protocol_module);
const shared_memory_server_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "shared-memory-server", "system/services/shared-memory-server/shared-memory-server.zig");
const shared_memory_client_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "shared-memory-client", "system/services/shared-memory-client/shared-memory-client.zig");
const fat_test_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "fat-test", "system/services/fat/fat-test.zig");
const pci_bus_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "pci-bus", "system/drivers/pci-bus/pci-bus.zig");
const shared_memory_server_exe = addUserBinary(b, kernel_target, &default_imports, "shared-memory-server", "system/services/shared-memory-server/shared-memory-server.zig");
const shared_memory_client_exe = addUserBinary(b, kernel_target, &default_imports, "shared-memory-client", "system/services/shared-memory-client/shared-memory-client.zig");
const fat_test_exe = addUserBinary(b, kernel_target, &default_imports, "fat-test", "system/services/fat/fat-test.zig");
const pci_bus_exe = addUserBinary(b, kernel_target, &default_imports, "pci-bus", "system/drivers/pci-bus/pci-bus.zig");
programModule(pci_bus_exe).addImport("device-manager-protocol", device_manager_protocol_module);
// The PCI bus driver decodes each function's class triple to human names in its
// boot log (class/subclass/prog-IF), so pull in the shared pci-class reference.
programModule(pci_bus_exe).addImport("pci-class", pci_class_module);
// A test fixture, not a real driver: hellos to the device manager, then faults
// what the driver-restart scenario drives the crash-loop cap with.
const crash_test_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "crash-test", "system/services/crash-test/crash-test.zig");
const crash_test_exe = addUserBinary(b, kernel_target, &default_imports, "crash-test", "system/services/crash-test/crash-test.zig");
programModule(crash_test_exe).addImport("device-manager-protocol", device_manager_protocol_module);
const device_list_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "device-list", "system/services/device-list/device-list.zig");
const device_list_exe = addUserBinary(b, kernel_target, &default_imports, "device-list", "system/services/device-list/device-list.zig");
programModule(device_list_exe).addImport("device-manager-protocol", device_manager_protocol_module);
// The discovery service: one swappable process per firmware
// (docs/discovery.md), bundled under the neutral ramdisk name
@ -749,11 +723,11 @@ pub fn build(b: *std.Build) void {
.acpi => "system/services/acpi/acpi.zig",
.fdt => "system/services/fdt/fdt.zig",
};
const discovery_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "discovery", discovery_source);
const discovery_exe = addUserBinary(b, kernel_target, &default_imports, "discovery", discovery_source);
if (discovery == .acpi) programModule(discovery_exe).addImport("aml", aml_module);
if (discovery == .acpi) programModule(discovery_exe).addImport("device-manager-protocol", device_manager_protocol_module);
if (discovery == .acpi) programModule(discovery_exe).addImport("power-protocol", power_protocol_module);
const device_manager_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "device-manager", "system/services/device-manager/device-manager.zig");
const device_manager_exe = addUserBinary(b, kernel_target, &default_imports, "device-manager", "system/services/device-manager/device-manager.zig");
// Names the xHCI PCI class triple from the shared taxonomy instead of a bare 0x0C0330.
programModule(device_manager_exe).addImport("pci-class", pci_class_module);
programModule(device_manager_exe).addImport("device-manager-protocol", device_manager_protocol_module);
@ -762,16 +736,16 @@ pub fn build(b: *std.Build) void {
programModule(device_manager_exe).addImport("usb-ids", usb_ids_module);
// The input service and its exercisers: the fan-out server, a hardware-free synthetic
// source, and a subscriber that doubles as the `input` test's oracle. See docs/input.md.
const input_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "input", "system/services/input/input.zig");
const input_exe = addUserBinary(b, kernel_target, &default_imports, "input", "system/services/input/input.zig");
programModule(input_exe).addImport("input-protocol", input_protocol_module);
const input_source_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "input-source", "system/services/input-source/input-source.zig");
const input_test_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "input-test", "system/services/input-test/input-test.zig");
const args_echo_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "args-echo", "system/services/args-echo/args-echo.zig");
const process_test_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "process-test", "system/services/process-test/process-test.zig");
const logger_exe = addUserBinary(b, kernel_target, &default_imports, runtime_module, "logger", "system/services/logger/logger.zig");
const input_source_exe = addUserBinary(b, kernel_target, &default_imports, "input-source", "system/services/input-source/input-source.zig");
const input_test_exe = addUserBinary(b, kernel_target, &default_imports, "input-test", "system/services/input-test/input-test.zig");
const args_echo_exe = addUserBinary(b, kernel_target, &default_imports, "args-echo", "system/services/args-echo/args-echo.zig");
const process_test_exe = addUserBinary(b, kernel_target, &default_imports, "process-test", "system/services/process-test/process-test.zig");
const logger_exe = addUserBinary(b, kernel_target, &default_imports, "logger", "system/services/logger/logger.zig");
// The first multi-threaded binary: exercises runtime.Thread over the thread ABI
// (docs/threading.md). Built threaded so its shared-memory poll is real.
const thread_test_exe = addThreadedUserBinary(b, kernel_target, &default_imports, runtime_module, "thread-test", "system/services/thread-test/thread-test.zig");
const thread_test_exe = addThreadedUserBinary(b, kernel_target, &default_imports, "thread-test", "system/services/thread-test/thread-test.zig");
// Every user binary and its FHS home on the boot volume. There is no packed
// ramdisk artifact any more: make-fat-image.py lays each binary out at this

View File

@ -1,25 +1,26 @@
//! The root module every user binary is compiled through (build.zig,
//! `addUserBinary`). The program's own file is imported as `program`, and this
//! shim contributes the declarations Zig resolves from the compilation root
//! `main` (dispatched by runtime.start) and the panic handler and pulls in the
//! `_start` entry shim. A program therefore only defines `pub fn main`; nothing
//! else is required in its source file.
//! `main` (dispatched by start's comptime dispatch) and the panic handler and
//! pulls in the `_start` entry shim. A program therefore only defines
//! `pub fn main`; nothing else is required in its source file.
const runtime = @import("runtime");
const start = @import("start");
const logging = @import("logging");
const program = @import("program");
/// Resolved as `@import("root").main` by runtime.start's comptime dispatch.
/// Resolved as `@import("root").main` by start's comptime dispatch.
pub const main = program.main;
/// The panic handler for every safety check in the image (runtime.start.panic).
pub const panic = runtime.panic;
/// The panic handler for every safety check in the image (start.panic).
pub const panic = start.panic;
/// std.log for every user binary goes to the tagged kernel log ring (the kernel
/// stamps the sender; see runtime.log). A program overrides by declaring its
/// own `pub const std_options`.
/// stamps the sender; see the logging module). A program overrides by declaring
/// its own `pub const std_options`.
pub const std_options: @import("std").Options =
if (@hasDecl(program, "std_options")) program.std_options else runtime.log.default_options;
if (@hasDecl(program, "std_options")) program.std_options else logging.default_options;
comptime {
_ = &runtime.start._start; // pull the runtime entry shim into the image
_ = &start._start; // pull the entry shim into the image
}

View File

@ -1,51 +0,0 @@
//! runtime.zig a **compatibility shim** for the runtime split (reorg C1C5).
//!
//! `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"); // 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;
// Device / service clients (now in library/device/driver, library/device/block, library/client).
pub const device = @import("driver");
pub const device_manager = @import("driver"); // hello() folded into driver
pub const input = @import("input");
pub const block = @import("block");
pub const display = @import("display");
/// The heap as a namespace (`runtime.heap.allocator()`), plus `runtime.allocator`.
pub const heap = struct {
pub const allocator = memory.allocator;
};
/// `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;
};
/// `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;
};

View File

@ -1,66 +0,0 @@
//! system.zig a **compatibility shim**, not the real home of anything anymore.
//!
//! The runtime's syscall surface used to be dumped here in one file. It has been split by
//! concern into `time` / `logging` / `process` / `file-system` / `memory`. This re-exports
//! the old flat `system.*` names from those homes so consumers that still write
//! `runtime.system.write` (etc.) keep compiling until they migrate to the concern modules.
//! Deleted once nothing references `runtime.system` (reorg step C5).
const memory = @import("memory");
const process = @import("process");
const time = @import("time");
const logging = @import("logging");
const file_system = @import("file-system");
// memory
pub const PROT_READ = memory.PROT_READ;
pub const PROT_WRITE = memory.PROT_WRITE;
pub const PROT_EXEC = memory.PROT_EXEC;
pub const mmap = memory.mmap;
pub const munmap = memory.munmap;
pub const mmapFailed = memory.mmapFailed;
// process
pub const ProcessDescriptor = process.ProcessDescriptor;
pub const yield = process.yield;
pub const exit = process.exit;
pub const spawn = process.spawn;
pub const spawnWithArguments = process.spawnWithArguments;
pub const spawnSupervised = process.spawnSupervised;
pub const processes = process.processes;
pub const isProcessRunning = process.isProcessRunning;
pub const kill = process.kill;
// time
pub const clock = time.clock;
pub const wallClock = time.wallClock;
pub const sleep = time.sleepMillis;
pub const timerOnce = time.timerOnce;
// logging
pub const write = logging.write;
pub const writeRecord = logging.writeRecord;
pub const klogRead = logging.klogRead;
pub const klogStatus = logging.klogStatus;
pub const KlogLevel = logging.KlogLevel;
pub const KlogStatus = logging.KlogStatus;
pub const KlogRecordHeader = logging.KlogRecordHeader;
pub const klog_record_header_size = logging.klog_record_header_size;
pub const klog_record_alignment = logging.klog_record_alignment;
pub const klog_record_magic = logging.klog_record_magic;
pub const klog_flag_truncated = logging.klog_flag_truncated;
pub const klog_maximum_message = logging.klog_maximum_message;
pub const maximum_process_name = logging.maximum_process_name;
// file-system
pub const FsRoute = file_system.FsRoute;
pub const fsResolve = file_system.fsResolve;
pub const fsNodeRead = file_system.fsNodeRead;
pub const fsNodeStatus = file_system.fsNodeStatus;
pub const fsNodeReaddir = file_system.fsNodeReaddir;
pub const fsMount = file_system.fsMount;
pub const fsUnmount = file_system.fsUnmount;
pub const FileAttributes = file_system.FileAttributes;
pub const DirectoryEntryHeader = file_system.DirectoryEntryHeader;
pub const file_kind_regular = file_system.file_kind_regular;
pub const file_kind_directory = file_system.file_kind_directory;