5.2 KiB
Phase 13.3: booted Fruix using native store-built FreeBSD base artifacts
Date: 2026-04-03
Goal
Phase 13.3 was the first end-to-end boot validation of the new native FreeBSD base path.
The target was a Fruix system/image that boots using:
- native
/usr/src-built kernel output in/frx/store - native
/usr/src-built world output in/frx/store - host-staged bootloader only, as the remaining explicit transitional boundary
Validation still followed the established strategy:
- local QEMU/UEFI/TCG
- real XCP-ng on the approved VM/VDI path
Issues found and fixed
1. The old fixed 256 MiB root filesystem image was too small
The first native-base image attempt failed during makefs with:
size of .../image-rootfs is larger than the maxsize of 268435456
That was expected once the image started carrying a native world instead of the earlier curated host-copy runtime slice.
To fix this cleanly, Fruix image generation gained an explicit root filesystem size parameter:
scripts/fruix.scmnow accepts:--root-size SIZE
- image metadata now emits:
root_size=...
tests/system/run-phase8-system-image.shnow accepts:ROOT_SIZEand records the reported root size in metadata
For the native-base boot validation, the working values were:
- local QEMU:
ROOT_SIZE=6gDISK_CAPACITY=8g
- real XCP-ng:
ROOT_SIZE=6g- disk capacity kept matched to the fixed 30 GiB VDI as before
2. materialize-bhyve-image needed to propagate native-base metadata
After adding the new native_base_* metadata path, the first native image run hit a Scheme error because materialize-bhyve-image still returned:
host-base-storesfruix-runtime-stores
but not:
native-base-stores
That was corrected so image-generation results now carry the native-base store set too.
Harness updates
Reused/extended existing Phase 11 boot harnesses
tests/system/run-phase11-shepherd-pid1-qemu.sh- now accepts
OS_TEMPLATElike the XCP-ng PID1 harness already did
- now accepts
tests/system/run-phase8-system-image.sh- now records:
native_base_store_countnative_base_storesroot_size
- now records:
Added native-base boot wrappers
New wrappers:
tests/system/run-phase13-native-base-qemu.shtests/system/run-phase13-native-base-xcpng.sh
These wrappers reuse the already-validated PID1 boot path but require the image metadata to confirm that the booted system really uses the intended Phase-13 base split:
native_base_store_count=2- native kernel present
- native world present
host_base_store_count=1- host base reduced to bootloader only
Validation
Local QEMU / UEFI / TCG
Passing run:
PASS phase13-native-base-qemu- workdir:
/tmp/phase13-3-qemu3-1775174863
Key metadata:
disk_capacity=8g
root_size=6g
native_base_store_count=2
host_base_store_count=1
shepherd_pid=1
sshd_status=running
native_base_boot=ok
The wrapped underlying Phase 11 PID1 harness also confirmed the full guest runtime path:
- ready marker present
/run/current-systemcorrect- Shepherd socket present
- Shepherd PID is
1 sshdrunning- activation completed successfully
/etc/login.confregular + databases present
Real XCP-ng VM
Passing run:
PASS phase13-native-base-xcpng- workdir:
/tmp/phase13-3-xcpng-1775175086
Key metadata:
vm_id=90490f2e-e8fc-4b7a-388e-5c26f0157289
vdi_id=0f1f90d3-48ca-4fa2-91d8-fc6339b95743
guest_ip=192.168.213.62
root_size=6g
native_base_store_count=2
host_base_store_count=1
shepherd_pid=1
sshd_status=running
compat_prefix_shims=absent
guile_module_smoke=ok
native_base_boot=ok
The dynamic VHD upload remained workable even with the larger native-world image payload, though naturally much larger than the earlier minimal image path:
- upload size:
4740784128bytes (~4.42 GiB)
What booted
The validated native-base system closure used:
- native kernel store:
/frx/store/93f35ddcb9a03f63f83c9e8ae29788685d339789da664f881822b4a1914f5ff6-freebsd-native-kernel-15.0-STABLE
- native world store:
/frx/store/3f6f7f8c06ed8dad4cae21a1e8ac8ba4823bdb7cf54328c9bbcccaeb858beb77-freebsd-native-world-15.0-STABLE
- remaining host base store:
/frx/store/8ffcfe0356fea815726b610514a1280a11266851c2acb870047d559795569f0e-freebsd-bootloader-15.0-STABLE
That means Phase 13 has now crossed its main success boundary:
- the kernel is native
- the core world runtime is native
- the system actually boots from those outputs
Assessment
Phase 13 is complete.
Fruix has now moved from:
- building a FreeBSD system from curated host copies
into:
- building kernel/world artifacts from
/usr/srcinto/frx/store, then booting a declarative Fruix system from those outputs.
The remaining major transitional boundary is now much narrower and explicit:
- host-staged bootloader/boot assets remain
- native kernel + native core world runtime are already in place
That is a real architectural shift, not just more documentation.
Next recommended step
Proceed to Phase 14:
- replace the remaining host-copy boot assets first
- then keep reducing the older host-staged FreeBSD base slice around the now-working native world/kernel path
- revisit cleaner runtime vs. development splits once the boot asset transition is done