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:
+27
-27
@@ -10,7 +10,7 @@
|
||||
//! exception report the handler prints (which also reaches serial).
|
||||
|
||||
const std = @import("std");
|
||||
const danos = @import("danos");
|
||||
const system = @import("system");
|
||||
const architecture = @import("architecture");
|
||||
const devices_broker = @import("devices-broker.zig");
|
||||
const platform = @import("platform");
|
||||
@@ -153,7 +153,7 @@ fn powerTest(comptime action: enum { off, reboot }) void {
|
||||
result();
|
||||
}
|
||||
|
||||
const BootInformation = danos.BootInformation;
|
||||
const BootInformation = system.BootInformation;
|
||||
|
||||
fn eql(a: []const u8, b: []const u8) bool {
|
||||
return std.mem.eql(u8, a, b);
|
||||
@@ -165,7 +165,7 @@ fn smoke(boot_information: *const BootInformation) void {
|
||||
|
||||
// The memory map has some usable RAM.
|
||||
const mm = boot_information.memory_map;
|
||||
const regions = @as([*]const danos.MemoryRegion, @ptrFromInt(danos.physicalToVirtual(mm.regions)))[0..mm.len];
|
||||
const regions = @as([*]const system.MemoryRegion, @ptrFromInt(system.physicalToVirtual(mm.regions)))[0..mm.len];
|
||||
var usable: u64 = 0;
|
||||
for (regions) |r| {
|
||||
if (r.kind == .usable) usable += r.pages;
|
||||
@@ -177,7 +177,7 @@ fn smoke(boot_information: *const BootInformation) void {
|
||||
const b = pmm.alloc();
|
||||
check("alloc returns a frame", a != null);
|
||||
check("alloc returns distinct frames", a != null and b != null and a.? != b.?);
|
||||
check("frames are page-aligned", (a orelse 1) % danos.page_size == 0);
|
||||
check("frames are page-aligned", (a orelse 1) % system.page_size == 0);
|
||||
|
||||
// Freeing restores the count.
|
||||
const before = pmm.stats().free_frames;
|
||||
@@ -187,7 +187,7 @@ fn smoke(boot_information: *const BootInformation) void {
|
||||
|
||||
// Paging is active on our own tables (the root is non-zero and page-aligned).
|
||||
const root = architecture.activePageTable();
|
||||
check("paging active (page-table root set)", root != 0 and root % danos.page_size == 0);
|
||||
check("paging active (page-table root set)", root != 0 and root % system.page_size == 0);
|
||||
|
||||
result();
|
||||
}
|
||||
@@ -573,7 +573,7 @@ fn smpTest() void {
|
||||
const tramp = architecture.trampolinePage();
|
||||
check("trampoline frame reserved", tramp != 0);
|
||||
if (tramp != 0) {
|
||||
const bytes: [*]const u8 = @ptrFromInt(danos.physicalToVirtual(tramp));
|
||||
const bytes: [*]const u8 = @ptrFromInt(system.physicalToVirtual(tramp));
|
||||
var zeroed = true;
|
||||
for (0..4096) |b| {
|
||||
if (bytes[b] != 0) zeroed = false;
|
||||
@@ -757,7 +757,7 @@ fn userMemTest() void {
|
||||
var mapped: usize = 0;
|
||||
while (mapped < npages) : (mapped += 1) {
|
||||
frames[mapped] = pmm.alloc() orelse break;
|
||||
architecture.mapUserPageInto(aspace, arena + mapped * danos.page_size, frames[mapped], true, false);
|
||||
architecture.mapUserPageInto(aspace, arena + mapped * system.page_size, frames[mapped], true, false);
|
||||
}
|
||||
check("granted three user pages", mapped == npages);
|
||||
|
||||
@@ -765,13 +765,13 @@ fn userMemTest() void {
|
||||
var translate_ok = true;
|
||||
var rw_ok = true;
|
||||
for (0..npages) |i| {
|
||||
const va = arena + i * danos.page_size;
|
||||
const va = arena + i * system.page_size;
|
||||
const physical = architecture.translate(aspace, va) orelse {
|
||||
translate_ok = false;
|
||||
continue;
|
||||
};
|
||||
if (physical != frames[i]) translate_ok = false;
|
||||
const p: [*]u8 = @ptrFromInt(danos.physicalToVirtual(physical));
|
||||
const p: [*]u8 = @ptrFromInt(system.physicalToVirtual(physical));
|
||||
p[0] = 0xA5;
|
||||
if (p[0] != 0xA5) rw_ok = false;
|
||||
}
|
||||
@@ -780,7 +780,7 @@ fn userMemTest() void {
|
||||
|
||||
// Release them the way munmap does, then tear down the address space.
|
||||
for (0..npages) |i| {
|
||||
const va = arena + i * danos.page_size;
|
||||
const va = arena + i * system.page_size;
|
||||
if (architecture.translate(aspace, va)) |physical| {
|
||||
architecture.unmapUserPageInto(aspace, va);
|
||||
pmm.free(physical);
|
||||
@@ -877,7 +877,7 @@ fn processTest(boot_information: *const BootInformation) void {
|
||||
result();
|
||||
return;
|
||||
}
|
||||
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.write_count = 0;
|
||||
process.write_from_user = false;
|
||||
@@ -928,7 +928,7 @@ fn initTest(boot_information: *const BootInformation) void {
|
||||
result();
|
||||
return;
|
||||
}
|
||||
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.write_count = 0;
|
||||
const spawned = if (process.spawnProcess(image, 4)) true else |err| blk: {
|
||||
log("DANOS-INIT-ERR: {s}\n", .{@errorName(err)});
|
||||
@@ -962,7 +962,7 @@ fn initialRamdiskTest(boot_information: *const BootInformation) void {
|
||||
result();
|
||||
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 {
|
||||
check("initial_ramdisk image is valid", false);
|
||||
result();
|
||||
@@ -1006,7 +1006,7 @@ fn vfsTest(boot_information: *const BootInformation) void {
|
||||
result();
|
||||
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 {
|
||||
check("initial_ramdisk image is valid", false);
|
||||
result();
|
||||
@@ -1069,7 +1069,7 @@ fn hpetTest(boot_information: *const BootInformation) void {
|
||||
result();
|
||||
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 {
|
||||
check("initial_ramdisk image is valid", false);
|
||||
result();
|
||||
@@ -1113,14 +1113,14 @@ fn hpetRouteOk() bool {
|
||||
|
||||
/// The GSI discovery recorded for the HPET, from the same device table the driver saw.
|
||||
fn hpetGsi() ?u32 {
|
||||
var buffer: [16]danos.DeviceDescriptor = undefined;
|
||||
var buffer: [16]system.DeviceDescriptor = undefined;
|
||||
const n = @min(devices_broker.enumerate(&buffer), buffer.len);
|
||||
for (buffer[0..n]) |d| {
|
||||
if (d.class != @intFromEnum(danos.DeviceClass.timer)) continue;
|
||||
if (d.parent != danos.no_parent) continue; // the block, not a comparator child
|
||||
if (d.class != @intFromEnum(system.DeviceClass.timer)) continue;
|
||||
if (d.parent != system.no_parent) continue; // the block, not a comparator child
|
||||
for (0..d.resource_count) |j| {
|
||||
const r = d.resources[j];
|
||||
if (r.kind == @intFromEnum(danos.ResourceKind.irq)) return @intCast(r.start);
|
||||
if (r.kind == @intFromEnum(system.ResourceKind.irq)) return @intCast(r.start);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -1146,7 +1146,7 @@ fn busTest(boot_information: *const BootInformation) void {
|
||||
result();
|
||||
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 {
|
||||
check("initial_ramdisk image is valid", false);
|
||||
result();
|
||||
@@ -1181,7 +1181,7 @@ fn busTest(boot_information: *const BootInformation) void {
|
||||
/// trusted and doesn't obey containment: a PCI function's BAR is not inside its host
|
||||
/// bridge's `bus_range`, because a bus-number range isn't an address window.
|
||||
fn childrenContained() bool {
|
||||
var buffer: [64]danos.DeviceDescriptor = undefined;
|
||||
var buffer: [64]system.DeviceDescriptor = undefined;
|
||||
const n = @min(devices_broker.enumerate(&buffer), buffer.len);
|
||||
|
||||
const bus_id = hpetDeviceId() orelse return false;
|
||||
@@ -1197,7 +1197,7 @@ fn childrenContained() bool {
|
||||
for (0..p.resource_count) |j| {
|
||||
const pr = p.resources[j];
|
||||
if (pr.kind != r.kind) continue;
|
||||
if (r.kind == @intFromEnum(danos.ResourceKind.irq)) {
|
||||
if (r.kind == @intFromEnum(system.ResourceKind.irq)) {
|
||||
if (pr.start == r.start) ok = true;
|
||||
} else if (r.len != 0 and r.start >= pr.start and
|
||||
r.start + r.len <= pr.start + pr.len) ok = true;
|
||||
@@ -1210,13 +1210,13 @@ fn childrenContained() bool {
|
||||
|
||||
/// Device id of the HPET (the bus bus claims), from the same table drivers see.
|
||||
fn hpetDeviceId() ?u64 {
|
||||
var buffer: [64]danos.DeviceDescriptor = undefined;
|
||||
var buffer: [64]system.DeviceDescriptor = undefined;
|
||||
const n = @min(devices_broker.enumerate(&buffer), buffer.len);
|
||||
for (buffer[0..n]) |d| {
|
||||
if (d.class != @intFromEnum(danos.DeviceClass.timer)) continue;
|
||||
if (d.parent != danos.no_parent) continue; // a comparator child, not the block
|
||||
if (d.class != @intFromEnum(system.DeviceClass.timer)) continue;
|
||||
if (d.parent != system.no_parent) continue; // a comparator child, not the block
|
||||
for (0..d.resource_count) |j| {
|
||||
if (d.resources[j].kind == @intFromEnum(danos.ResourceKind.memory)) return d.id;
|
||||
if (d.resources[j].kind == @intFromEnum(system.ResourceKind.memory)) return d.id;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -1310,7 +1310,7 @@ fn ioPassTest() void {
|
||||
return;
|
||||
};
|
||||
// Map it the way mmio_map does (device grant), then tear the space down.
|
||||
architecture.mapUserDeviceInto(aspace, process.device_arena_base, frame, danos.page_size);
|
||||
architecture.mapUserDeviceInto(aspace, process.device_arena_base, frame, system.page_size);
|
||||
architecture.destroyAddressSpace(aspace);
|
||||
|
||||
// The page tables were reclaimed; the device-granted frame must not have been.
|
||||
|
||||
Reference in New Issue
Block a user