Rename the shared contract module danos -> system; QEMU logs to /var/log/system

The shared kernel<->user ABI contract (BootInformation, the SystemCall numbers,
DeviceDescriptor, page_size, ...) is now the `system` module at
system/system.zig, following the convention that a directory's root file takes
the directory's name.

One overlap to note: the runtime's syscall wrappers are already `runtime.system`,
so the single file that uses both the contract and those wrappers
(library/runtime/heap.zig) aliases the wrappers locally as `system_calls`. The
two are distinct (top-level `system` vs `runtime.system`); everywhere else the
contract is just `system`.

Also: the QEMU run's serial capture now lands in the FHS log location,
zig-out/var/log/system/serial0-<timestamp>.log — a stand-in for the kernel's own
logging system, which will eventually write there itself.

Suite 35/35 plus host tests green.
This commit is contained in:
Daniel Samson
2026-07-10 14:09:38 +01:00
parent 3d1de37d0e
commit d19a0ae38d
38 changed files with 202 additions and 198 deletions
+12 -12
View File
@@ -1,5 +1,5 @@
const std = @import("std");
const danos = @import("danos");
const system = @import("system");
const parameters = @import("parameters");
const architecture = @import("architecture");
const console = @import("console.zig");
@@ -14,14 +14,14 @@ const initial_ramdisk = @import("initial-ramdisk");
const platform = @import("platform");
const tests = @import("tests.zig");
const build_options = @import("build_options");
const BootInformation = danos.BootInformation;
const BootInformation = system.BootInformation;
/// The calling convention used to enter the kernel. Pinned to SystemV explicitly:
/// the bootloader is built for the UEFI target, whose C convention is Microsoft
/// x64 (first argument in RCX), while the kernel is SystemV (first argument in
/// RDI). Both sides reference this so the `boot_information` pointer lands in the
/// register the other expects. `danos.kernel_abi` re-exports it to the loader.
pub const kernel_abi = danos.kernel_abi;
/// register the other expects. `system.kernel_abi` re-exports it to the loader.
pub const kernel_abi = system.kernel_abi;
// POST/checkpoint codes emitted to I/O port 0x80 at boot milestones — the
// last-resort progress signal on a machine with no text output at all.
@@ -50,7 +50,7 @@ var ap_trampoline_page: u64 = 0;
/// half. `boot_information` (also low) is reached through the physmap — its base is the
/// same under the loader's bootstrap tables and the kernel's own.
export fn kmainEntry(boot_information: *const BootInformation) callconv(kernel_abi) noreturn {
kmain(@ptrFromInt(danos.physicalToVirtual(@intFromPtr(boot_information))));
kmain(@ptrFromInt(system.physicalToVirtual(@intFromPtr(boot_information))));
}
fn kmain(boot_information: *const BootInformation) noreturn {
@@ -91,7 +91,7 @@ fn kmain(boot_information: *const BootInformation) noreturn {
// Summarise the physical memory the loader handed us. The array is danos's
// own MemoryRegion, so this is a plain slice — no firmware layout in sight.
const regions = @as([*]const danos.MemoryRegion, @ptrFromInt(danos.physicalToVirtual(boot_information.memory_map.regions)))[0..boot_information.memory_map.len];
const regions = @as([*]const system.MemoryRegion, @ptrFromInt(system.physicalToVirtual(boot_information.memory_map.regions)))[0..boot_information.memory_map.len];
var usable_pages: u64 = 0;
var reserved_pages: u64 = 0; // reserved RAM only — MMIO is device space, not RAM
for (regions) |r| {
@@ -102,7 +102,7 @@ fn kmain(boot_information: *const BootInformation) noreturn {
}
}
const total_pages = usable_pages + reserved_pages;
const total_bytes = total_pages * danos.page_size;
const total_bytes = total_pages * system.page_size;
const gib = 1 << 30;
log.write("\ndanos: physical memory\n");
@@ -277,7 +277,7 @@ fn kmain(boot_information: *const BootInformation) noreturn {
// borrowing. This boot context then becomes the BSP's idle loop.
if (boot_information.init_len != 0) {
status("starting /sbin/init...\n");
const image = @as([*]const u8, @ptrFromInt(danos.physicalToVirtual(boot_information.init_base)))[0..boot_information.init_len];
const image = @as([*]const u8, @ptrFromInt(system.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)});
};
@@ -300,9 +300,9 @@ fn kmain(boot_information: *const BootInformation) noreturn {
/// Spawn every program bundled in the initial_ramdisk as its own ring-3 process. A bad
/// image or a program that fails to load is logged and skipped — the rest of the
/// system still runs.
fn startInitialRamdiskBinaries(boot_information: *const danos.BootInformation) void {
fn startInitialRamdiskBinaries(boot_information: *const system.BootInformation) void {
if (boot_information.initial_ramdisk_len == 0) return;
const image = @as([*]const u8, @ptrFromInt(danos.physicalToVirtual(boot_information.initial_ramdisk_base)))[0..boot_information.initial_ramdisk_len];
const image = @as([*]const u8, @ptrFromInt(system.physicalToVirtual(boot_information.initial_ramdisk_base)))[0..boot_information.initial_ramdisk_len];
const rd = initial_ramdisk.Reader.init(image) orelse {
status("initial_ramdisk: bad image, skipping\n");
return;
@@ -386,11 +386,11 @@ fn statusPrint(comptime fmt: []const u8, args: anytype) void {
/// Frames (4 KiB pages) to whole MiB.
fn mib(pages: u64) u64 {
return pages * danos.page_size / (1024 * 1024);
return pages * system.page_size / (1024 * 1024);
}
fn kib(frames: u64) u64 {
return frames * danos.page_size / (1024);
return frames * system.page_size / (1024);
}
/// Report a CPU exception and halt **this core**. There's no fault recovery yet, so