reorg: move test fixtures to test/system/services (source + boot volume)
The 11 QEMU-suite fixtures lived mixed into system/services/ with their binaries bundled at /system/tests/<name>. Now the repo path is the boot path, like every real service: test/system/services/<name>. fat-test moves out of the fat server's directory into its own; display-demo stays a boot service. - kernel VFS: setInitialRamdisk derives one read-only initrd mount per top-level tree named by the ramdisk entry paths (/system, /test), registers ancestors generically with self-parented roots, and refuses backend shadowing of any initrd tree - EFI loader: the fallback walk also enumerates \test (optional — a volume without fixtures still boots); manifest and capsule unchanged - path literals: vfs-test self-open + create probe, process-test process_enumerate matches, the args-echo argv[0] expectation; the kvfs case now covers the /test root end to end - docs: DFHS /test rows, tree diagrams, loader prose, and the location convention gain the third home; fixed the input-source link 100/100 QEMU cases pass.
This commit is contained in:
+22
-14
@@ -16,11 +16,12 @@ const MemoryMapSlice = uefi.tables.MemoryMapSlice;
|
||||
/// The kernel image: /system/kernel.
|
||||
const kernel_file_name = std.unicode.utf8ToUtf16LeStringLiteral("system\\kernel");
|
||||
|
||||
/// The user binaries: everything under /system except the kernel itself. The
|
||||
/// loader walks this tree and packs it into the in-RAM initial_ramdisk image —
|
||||
/// the volume's file structure is the single source of truth (no packed image
|
||||
/// artifact on disk).
|
||||
/// The user binaries: everything under /system except the kernel itself, plus
|
||||
/// the test fixtures under /test. The loader walks both trees and packs them
|
||||
/// into the in-RAM initial_ramdisk image — the volume's file structure is the
|
||||
/// single source of truth (no packed image artifact on disk).
|
||||
const system_directory_name = std.unicode.utf8ToUtf16LeStringLiteral("system");
|
||||
const test_directory_name = std.unicode.utf8ToUtf16LeStringLiteral("test");
|
||||
|
||||
/// Physical page size, and the sentinel UEFI uses to seek to end-of-file.
|
||||
const page_size = 4096;
|
||||
@@ -364,16 +365,17 @@ fn handoff(cr3: u64, entry: usize, boot_information: *const BootInformation) nor
|
||||
unreachable;
|
||||
}
|
||||
|
||||
// --- the /system tree -> initial_ramdisk ------------------------------------
|
||||
// --- the /system and /test trees -> initial_ramdisk --------------------------
|
||||
|
||||
/// Cap on bundled binaries. Generous: the tree carries ~30 today.
|
||||
const maximum_bundled = 64;
|
||||
|
||||
/// How deep the walk goes below /system ("/system/services/x" is depth 1).
|
||||
/// How deep the walk goes below a tree root ("/system/services/x" is depth 1,
|
||||
/// "/test/system/services/x" is depth 2).
|
||||
const maximum_tree_depth = 3;
|
||||
|
||||
/// One binary discovered under /system: its FHS path (UTF-8, '/'-separated,
|
||||
/// NUL-free) and its contents in a transient pool buffer.
|
||||
/// One binary discovered under a walked tree: its FHS path (UTF-8,
|
||||
/// '/'-separated, NUL-free) and its contents in a transient pool buffer.
|
||||
const Bundled = struct {
|
||||
path: [initial_ramdisk.maximum_name]u8,
|
||||
path_len: usize,
|
||||
@@ -389,10 +391,10 @@ const Bundled = struct {
|
||||
/// 1. /system/manifest (written by the build): each listed path is opened BY
|
||||
/// NAME — the case-insensitive lookup every firmware FAT driver gets
|
||||
/// right, and the only file access the pre-tree loader ever used.
|
||||
/// 2. No manifest: ENUMERATE the /system tree. Portable in principle, but
|
||||
/// firmware differs in what names enumeration returns (bare 8.3 entries
|
||||
/// come back uppercase on some drivers), so this is the fallback for
|
||||
/// hand-assembled sticks, not the primary path.
|
||||
/// 2. No manifest: ENUMERATE the /system and /test trees. Portable in
|
||||
/// principle, but firmware differs in what names enumeration returns
|
||||
/// (bare 8.3 entries come back uppercase on some drivers), so this is
|
||||
/// the fallback for hand-assembled sticks, not the primary path.
|
||||
fn loadSystemTree(bs: *uefi.tables.BootServices, boot_information: *BootInformation) !void {
|
||||
const loaded = (try bs.handleProtocol(uefi.protocol.LoadedImage, uefi.handle)) orelse
|
||||
return error.NoLoadedImage;
|
||||
@@ -426,6 +428,11 @@ fn loadSystemTree(bs: *uefi.tables.BootServices, boot_information: *BootInformat
|
||||
const system_directory = try root.open(system_directory_name, .read, .{});
|
||||
defer _ = system_directory.close() catch {};
|
||||
try walkDirectory(bs, system_directory, "/system", 0, &list, &count);
|
||||
// The /test tree is optional: a stick without fixtures still boots.
|
||||
if (root.open(test_directory_name, .read, .{})) |test_directory| {
|
||||
defer _ = test_directory.close() catch {};
|
||||
try walkDirectory(bs, test_directory, "/test", 0, &list, &count);
|
||||
} else |_| {}
|
||||
}
|
||||
if (count == 0) return error.NoBinaries;
|
||||
|
||||
@@ -452,7 +459,7 @@ fn loadSystemTree(bs: *uefi.tables.BootServices, boot_information: *BootInformat
|
||||
|
||||
boot_information.initial_ramdisk_base = @intFromPtr(image.ptr);
|
||||
boot_information.initial_ramdisk_len = total;
|
||||
log("EFI: /system tree loaded, starting the kernel\r\n");
|
||||
log("EFI: boot tree loaded, starting the kernel\r\n");
|
||||
}
|
||||
|
||||
/// The boot capsule: the bundled binaries as one v2 initial_ramdisk image.
|
||||
@@ -522,7 +529,8 @@ fn loadByManifest(bs: *uefi.tables.BootServices, root: *uefi.protocol.File, list
|
||||
|
||||
/// Recursively collect the regular files below `directory` into `list`. Top-level
|
||||
/// files (depth 0) are skipped: the only one is /system/kernel, which loadKernel
|
||||
/// has already consumed and which is not a spawnable user binary.
|
||||
/// has already consumed and which is not a spawnable user binary (/test has no
|
||||
/// top-level files, so the skip is a no-op there).
|
||||
fn walkDirectory(
|
||||
bs: *uefi.tables.BootServices,
|
||||
directory: *uefi.protocol.File,
|
||||
|
||||
Reference in New Issue
Block a user