This is the operational reference for the build host and the patch-build-deploy loop. For the narrative — why these constraints exist and what we tried before settling on them — see essay 3, “Building from source on honor”.
Build host
honor is the only machine we cross-build on.
- Reachable as
ssh honor(key auth, no password) - FreeBSD 15.0-RELEASE amd64
- 16 CPU cores, 672 GB free on
zroot - In-tree clang 19.1.7 — never the gcc14 from packages
- Source tree at
~/pine64-freebsd/honeyguide/freebsd-srcon thestable/15branch - Object dir at
~/pine64-freebsd/honeyguide/obj.clang(kept separate so other projects on the box don’t collide) - A second checkout at
~/drm-subtreeholds the out-of-tree DRM panfrost stack; the patch pipeline copies it on top offreebsd-srcbefore our overlays apply
A clean buildkernel is about 5 minutes. An incremental rebuild after
touching one driver file is around 18 seconds.
Why stable/15 + clang specifically
- Don’t use
main(16-CURRENT). The SDIO bus method ABI shifts under us; KASAN was on by default at one point and broke our modules. - Don’t use
releng/14. The drm-subtree was missing IRQ infrastructure we needed and the panfrost backport hadn’t happened. - Don’t use gcc14. See the claim above.
- Don’t run
honeyguide/cross-build.sh. It hardcodes gcc14 for historical reasons and modules will silently fail to load. Usemise run build-kernelinstead — it’s hardwired to clang.
The patch pipeline
mise run patch does, in order:
honeyguide/patch.sh—git reset --hardonfreebsd-src, then apply the Honeyguide overlays and patches on top of stock stable/15.cp -r ~/drm-subtree/* freebsd-src/sys/dev/drm/— drop the full out-of-tree DRM panfrost stack on top.cp -r ../src/* freebsd-src/— apply our overlays. These override anything Honeyguide or drm-subtree shipped, file-for-file.- For every
*.patchunder../patches/,patch -p0it onto the matching path infreebsd-src/.
The git reset --hard is destructive. Never edit freebsd-src/
directly on honor — anything you change there gets wiped on the next
mise run patch. Always edit in this repo, push, pull on honor, then
run patch.
mise tasks
mise run patch # sync overlays + apply patches
mise run build-kernel # full PINEPHONE_PRO buildkernel (clang)
mise run build-module bcm_hostwake # single module
mise run build-dtb # rebuild base DTB (rare; we use overlays)
mise run build # patch + build-dtb + build-kernel
mise run create-image # clean expandable SD image
mise run create-image-preloaded # image with X11 + omfreebdy + packages
mise run install <drive> # copy kernel + DTB to mounted SD card
mise run flash # dd image to phone in UMS mode
mise run boot # tap U-Boot menu over serial to boot
mise run image # full pipeline: sync + build + create-image-preloaded
mise run sync # rsync local repo → honor (alternative to git push)
Task definitions live in mise.toml
at the repo root.
The deploy step
Kernels build on honor; the phone runs them; the laptop sits in the middle. We pipe through it rather than letting honor push directly to the phone, both because honor doesn’t have routing to the phone’s USB network and because we want one canonical workflow regardless of where honor lives.
ssh honor 'cat ~/pine64-freebsd/honeyguide/obj.clang/.../kernel/kernel' \
| ssh pinephone 'sudo tee /boot/kernel/kernel > /dev/null'
ssh pinephone 'sudo reboot' ssh pinephone resolves to the phone’s USB-Ethernet IP (10.0.0.2 in
our setup; see essay 4). The phone reboots, the kernel comes up, and
serial console is captured to a local log file (always — see the
serial capture rule).
The git workflow rule
All code changes happen locally in this repo. The flow is:
- Edit
src/,patches/,sys/, etc. on the laptop git commit && git push origin masterssh honor 'cd ~/pine64-freebsd && git pull'mise run patch && mise run build-kernel- Pipe + reboot as above
Never rsync or scp directly to honor’s freebsd-src. The
git reset --hard in patch.sh will wipe it. Everything has to flow
through git so the source of truth stays in one place and Honeyguide’s
upstream-merge flow stays clean.
Build smoke test
If a kernel built on honor hangs at boot but a kernel from a known-good
day boots fine, the suspect is almost always a stale object directory or
a buildworld/kernel mismatch. The recovery is rm -rf ~/pine64-freebsd/honeyguide/obj.clang && mise run build — it costs ten
minutes but isolates the variable.