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

177 lines
5.6 KiB
Markdown

# 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:
```text
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:
```text
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.
## 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