Files
fruix/docs/reports/phase13-native-world-kernel-build-freebsd.md

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-kernel
  • freebsd-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.log
  • buildkernel-GENERIC.log
  • install-freebsd-native-world.log
  • install-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=1
  • host_base_stores= bootloader only
  • native_base_store_count=2
  • native_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.in
  • tests/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-stores in 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.

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