5.6 KiB
Phase 13.2: built the first native FreeBSD world and kernel artifacts from /usr/src
Date: 2026-04-03
Goal
After Phase 13.1 introduced native Fruix package/materialization support for FreeBSD base artifacts, the next step was to exercise that path for real:
- build a kernel from
/usr/src - build and stage a minimal runtime-oriented world from
/usr/src - place both outputs under
/frx/store - document the exact split of this first native base target
Implementation
1. Fixed two important builder issues found during the first real run
MAKEOBJDIRPREFIX had to move to the environment
The first real buildworld attempt failed with:
MAKEOBJDIRPREFIX can only be set in environment or src-env.conf(5)
The native build path originally passed MAKEOBJDIRPREFIX=... as a make command-line variable. That was corrected so the generated build command now uses:
env MAKEOBJDIRPREFIX=... make ...
instead.
The initial /usr/src tree hash was accidentally unstable
The first source-tree hashing attempt hashed the raw mtree -c output. That was subtly wrong because mtree includes header comments such as:
- date
- user
- machine
- tree path banner
As a result, successive hash computations differed even when /usr/src had not changed.
This was corrected by stripping the leading # ... comment lines before hashing the mtree content. After that fix:
- native world and native kernel reported the same
source-tree-sha256 - both reused the same native build root
- output identity stopped drifting on each run
First concrete native outputs
A native Fruix system definition using:
freebsd-native-kernelfreebsd-native-world- host-staged
freebsd-bootloader shepherd-pid1
was built successfully.
Resulting store outputs:
- kernel:
/frx/store/93f35ddcb9a03f63f83c9e8ae29788685d339789da664f881822b4a1914f5ff6-freebsd-native-kernel-15.0-STABLE
- world:
/frx/store/3f6f7f8c06ed8dad4cae21a1e8ac8ba4823bdb7cf54328c9bbcccaeb858beb77-freebsd-native-world-15.0-STABLE
Native build metadata records for both outputs show:
source-root=/usr/src- the same
source-tree-sha256 kernconf=GENERIC- the same shared
build-root
Shared build root:
/var/tmp/fruix-freebsd-native-build-c59b1b8128b305d9bad9cf3d654771c941c4e8b6a2732f6bc959df96d1d32f58
Key log files recorded in the output metadata:
buildworld.logbuildkernel-GENERIC.loginstall-freebsd-native-world.loginstall-freebsd-native-kernel.log
First native world split
The first freebsd-native-world output is intentionally runtime-oriented. Validation confirmed that it contains the core pieces needed by the existing Fruix guest model, including:
/bin/sh/sbin/init/etc/rc/usr/sbin/sshd/sbin/dhclient/usr/bin/cap_mkdb/usr/sbin/pwd_mkdb/usr/share/locale/C.UTF-8/LC_CTYPE
The first prune list is also active. Validation confirmed the world output does not contain:
/usr/share/man/usr/tests
This keeps the first native world output closer to the current boot/runtime target instead of a fully unpruned base install tree.
Store-boundary result
The generated closure metadata now shows the intended transitional boundary clearly:
host_base_store_count=1host_base_stores=bootloader onlynative_base_store_count=2native_base_stores=native kernel + native world
That means Fruix now has a mixed but explicit Phase-13 system boundary:
- bootloader still comes from the old host-staged path
- kernel and core runtime world now come from native
/usr/src-built store outputs
Validation
Direct build through fruix system build
A real native-base system build succeeded and produced:
- native kernel store output
- native world store output
- a system closure referencing those outputs
Dedicated Phase 13.2 harness
Added:
tests/system/phase13-native-base-pid1-operating-system.scm.intests/system/run-phase13-native-base-build.sh
Passing run:
PASS phase13-native-base-build- workdir:
/tmp/phase13-2-build-1775173551
Key metadata from that run:
kernel_store=/frx/store/93f35ddcb9a03f63f83c9e8ae29788685d339789da664f881822b4a1914f5ff6-freebsd-native-kernel-15.0-STABLE
world_store=/frx/store/3f6f7f8c06ed8dad4cae21a1e8ac8ba4823bdb7cf54328c9bbcccaeb858beb77-freebsd-native-world-15.0-STABLE
host_base_store_count=1
native_base_store_count=2
world_source_tree_sha256=72a451e2ea47c4c4777035f797dc35f8d905eaabb2a717bc1fd71019f3021f72
kernel_source_tree_sha256=72a451e2ea47c4c4777035f797dc35f8d905eaabb2a717bc1fd71019f3021f72
world_build_root=/var/tmp/fruix-freebsd-native-build-c59b1b8128b305d9bad9cf3d654771c941c4e8b6a2732f6bc959df96d1d32f58
kernel_build_root=/var/tmp/fruix-freebsd-native-build-c59b1b8128b305d9bad9cf3d654771c941c4e8b6a2732f6bc959df96d1d32f58
The harness also verified:
- closure rebuild path reproducibility
- existence of required kernel/world runtime files
- absence of the pruned world paths
- presence of native build metadata and logs
- presence of
native-base-storesin closure store-layout metadata
Assessment
Phase 13.2 is complete.
Fruix now does more than describe native FreeBSD base artifacts: it actually builds them from /usr/src, stores them under /frx/store, and records enough metadata to inspect how they were produced.
This is the first point where Fruix can honestly say that part of the FreeBSD base is no longer just a curated copy of the builder host.
Next recommended step
Proceed to Phase 13.3:
- wire the operating-system/image path to boot using these native kernel/world outputs
- validate locally with QEMU/UEFI
- validate on the approved XCP-ng VM/VDI path