rpi5_native_boot() populates the existing BootInfo struct from the devicetree instead of UEFI protocols, then calls the existing, unmodified kernel_main() -- the crux of why most of M1-M9 stays shared between the UEFI and native boot paths. native_rpi5_entry.S now tail-calls into it instead of halting. memory_map is built from /memory's own reg, honoring the *root* node's #address-cells/#size-cells (confirmed against bcm2712.dtsi's actual root node -- <2>/<2> -- not assumed; a wrong cell width here would compile and boot clean in QEMU while silently corrupting the real memory map on real silicon). Required a new fdt_find_node_by_device_type() since /memory is identified by device_type = "memory" per DT spec, not compatible. args comes from /chosen's bootargs fed into the existing cmdline_parse_ascii() (confirmed pure C99 with no UEFI coupling before reusing it). framebuffer comes from the already-built rpi5_mailbox_get_framebuffer() at a fixed 1920x1080x32 default -- no EDID query exists in this codebase, flagged rather than guessed past. Deliberately scoped out, not silently skipped: /reserved-memory is not parsed. Carving reserved sub-ranges out of /memory's span needs interval-splitting logic that would be written blind against hardware not yet in hand -- exactly the kind of code that hides a bug until real silicon. pmm.c's Pass 3 only ever clears pages this file lists as EfiConventionalMemory, so the gap is "less usable RAM than optimal," never "reserved RAM wrongly marked free." Left as its own future item. Also fixes a real link failure this work surfaced: boot/cmdline.c was only in LOADER_SRCS_BASE (the .efi target), not KERNEL_SRCS_BASE (the separate .elf target arch/aarch64/*.c also wildcards into) -- added it there too. Compile-only-verified; nothing in the existing UEFI/QEMU path calls rpi5_native_boot(), so this cannot be exercised until real hardware. Verified 3-arch boot to ok>/zuse)ok>. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019YcT3H2PQeyujrzjqS3Var
disk/
QEMU disk images used for Artemis (block-storage VM) persistence testing.
Mounted via Makefile.starkernel's ARTDISK variable (default
disk/artemis.img) as a virtio-blk-pci device on all three
architectures' kernel QEMU boots — not scripts/rundisk.sh, which targets
a separate, currently-unused disks/ (plural) directory for the hosted
VM's --disk-img= flag instead.
artemis.img— standard Artemis persistence test disk. Reformatted 2026-08-02: this image had been stuck in a corrupted state (validLithosAnankemagic header, but data not matching whatART-READ-TESTexpects) since before this repo's own git history begins (git logshows it already broken at the initial commit, carried over from the pre-split monorepo). Chasing down the resulting persistentFAIL: persist-readtraced to the data, not the code — the write→reboot→read round trip works correctly on a fresh image (seeartemis-debug-roundtrip.imgbelow). Reformatted by blanking the file and letting a normal boot format+write-test it; verifiedPASS: persist-readon amd64, aarch64, and riscv64 against the same image afterward (cross-arch resume, matching the arch-neutral on-disk format.claude/ARTEMIS.mdspecifies).artemis-debug-roundtrip.img— round-trip regression fixture created during that investigation. Known-good: format → self-test → write-test → reboot → resume →PASS: persist-read, confirmed 3 times in a row. Keep this in a passing state; if a future change breaks it, that's a real regression, not a stale-fixture artifact likeartemis.imgwas.artemis-persist-test.img— persistence round-trip test image (pre-existing; history/state not re-verified during the above investigation).artemis-poison.img— a separate test image (exact scenario not documented elsewhere in the repo as of this writing; name suggests an adversarial/corruption test, not confirmed).artemis-unrecognized-test.img— exercisesART-HALT-UNRECOG(.claude/ARTEMIS.mdacceptance criterion #6). Regenerated 2026-08-02: the previous copy of this file had itself been silently reformatted by a since-fixed bug in the generic block subsystem (src/block_subsystem.c) — it carried a valid low-level'STFR'/v2 header despite being meant to represent foreign disk content, direct forensic evidence of the bug described in.claude/ARTEMIS.md's Build Status item 6. Regenerated as 30MB of a repeatingPOISON-UNRECOGNIZED-DISK-TEST-FIXTURE--NOT-BLANK-NOT-STFR-NOT-ARTEMIS--ASCII pattern — deliberately neither blank, nor the block subsystem's own'STFR'magic, nor Artemis's"ARTEMIS\0"marker. Verified on amd64 and riscv64 post-fix: boot correctly halts (ARTEMIS HALT: unrecognized disk content) and the file's sha256 is now byte-for-byte identical before and after boot. Keep this fixture in this poisoned state — if a future change makes its sha256 change across a boot, that is exactly the regression this fixture exists to catch.
Note on incidental header churn: artemis.img picks up a few changed
header bytes on every ordinary boot even though no user data changes —
blk_subsys_attach_device() always records a fresh mounted_time on a
successfully recognized disk, which gets flushed at shutdown. This is
expected bookkeeping, not a bug; revert it before committing rather than
carrying timestamp noise in git history.
-
usb-thumbdrive-test.img— 64MB raw image backing a QEMUusb-storagedevice attached to the xHCI controller's bus (xhci0.0) for Milestone 2e/ 2h hotplug testing, added 2026-08-22. Blank (all zero) —blkio_usb.c+blk_subsys_attach_device()wiring (Milestone 2h, done 2026-08-25) attach it asBLK_FMT_PROVISIONALevery time, which is the intended, exercised state; not yetBLK_FMT_FORMATTEDviaBLK-CONFIRM-FORMAT. -
usb-thumbdrive-test2.img— 64MB raw image, added 2026-08-25 for Milestone 2h hot-detach/re-attach verification. Filled with a repeatingHOTDETACH-REATTACH-FIXTURE-2026-08-25--ASCII pattern, deliberately distinguishable fromusb-thumbdrive-test.img's all-zero content — the point is proving a block read after detachingusb-thumbdrive-test.imgand re-attaching this one actually returns this pattern rather than silently replaying the old device's cached (all-zero) content, which is exactly the class of bug a same-LBN-range device swap can cause if the VM block window cache (vm->blk_vm_cbuf[]) isn't re-validated on a hit. -
artemis-reloc-test.img— 64MB raw image, added 2026-08-25 for single-block relocation (RELOCATE-BLOCK) persistence verification. Blank at creation; a genuinely fresh volume was required (notartemis.img) because relocation-table capacity (reloc_start/reloc_devblocksinblk_volume_meta_t) is only reserved byblk_compute_fresh_geometry()on a fresh format —artemis.imgpredates the feature and correctly reads backreloc_devblocks=0from what was previously unused header padding. Attach viamake -f Makefile.starkernel ARTDISK=disk/artemis-reloc-test.img ...(the Makefile'sARTDISKvar is?=-overridable). Not yetBLK-CONFIRM-FORMAT-committed in the repo copy — commit that step live if reusing this fixture for further reloc-table testing. -
artemis-metafence-fresh.img— 30MB raw image, blank at creation, added 2026-08-26 for the top-of-device system-metadata fence (meta_fence_blocksinblk_volume_meta_t, FABRIC-2.md Phase 8 §C). Same reasoning asartemis-reloc-test.imgabove: the fence is only initialized toBLK_META_FENCE_INIT(128) byblk_compute_fresh_geometry()on a fresh format, so a genuinely blank volume was needed to exercise that path. Verified round-trip: fresh format writes 128 (confirmed via direct byte read at header offset 184, independent of kernel self-report), a second boot without reformatting reads it back unchanged. Keep in its formatted (meta_fence_blocks=128) state — a future change that resets or corrupts this on reload is a real regression. -
artemis-metafence-test.img— 30MB raw image, a direct copy of the pre-existing (pre-fence)artemis.img, added 2026-08-26 alongside the fixture above to verify the other direction: an old volume that predatesmeta_fence_blockscorrectly reads it back as 0 (graceful default via zeroed former padding, not corruption) rather than crashing or misreading adjacent fields. -
zuse.img— 64MB raw image simulating the physical Zuse superuser thumbdrive for QEMU testing (FABRIC-2.md, Phase 8:zuse.img"bleach" mechanism, added 2026-08-26). 64MB is only this fixture's size, not a constraint on real home-blocks thumbdrives (Captain Bob, 2026-08-26) — the design is not bound to any particular drive size;homeblocks_sig_t's ownmetadata_devblocksfield records whatever size is actually observed on a real drive, nothing in the format hardcodes one. 64MB here is purely an arbitrary QEMU-test convenience (matchingusb-thumbdrive-test.img's existing precedent for BOT driver testing scale); usescripts/bleach_zuse_img.sh --size-mb Nfor a different test size. Blank (all zero) at creation — reads back asHOMEBLOCKS_SIG_BLANKviahomeblocks_sig_check(), confirmed live (xhci: USB drive not recognized (blank or foreign media)), simulating a genuine first boot for exercising the still-to-be-built one-time mint-Zuse flow. "Bleach" it back to this pristine/unminted state withscripts/bleach_zuse_img.shbefore each first-boot test run, rather than hand-regenerating the file — same all-zero content either way, the script just makes the reset a single documented, repeatable command. Deliberately a flat/raw image, not GPT-partitioned, matchinghomeblocks_sig_check()'s current call site (repl.c,sig_start_fblock=0) — both will move to a real GPT-partition-relative offset together once a GPT parser exists, not attempted ahead of that.
Convention, standing as of 2026-08-22: every virtual disk/thumb-drive image
used for testing — Artemis persistence disks above, and USB Mass Storage
backing images alike — lives in this directory and is a tracked, committed
file, never scratchpad. This was already artemis.img's convention;
usb-thumbdrive-test.img and any future USB test images follow the same
rule. Confirmed no .gitignore in this repo excludes disk/*.img.
These are regenerable QEMU raw disk images, not source — see
.claude/ARTEMIS.md for the storage model they exercise.