Watch
1
0
Fork
You've already forked SouveraineOS
0
SouveraineOS/saf/device/build.md
Fimeg bde961c6f2 saf: one spine — device, state, and work under the index
PAF becomes saf/device (history kept), STATE.md dissolves
into saf/state.md with the dated era archived, the substrate
SAF moves up from souveraine, and every agreement points at
saf/INDEX.md and nowhere else. one map, nothing to remember
2026-08-18 09:47:30 -04:00

3.3 KiB

PAF · Build & deploy (Arch era)

The loop that turns a kernel commit into a verified boot on glass. pmOS-era pmbootstrap notes preserved at evidence/build-pmos-era.md — dead path now.

The three places

Where Role
gitea 10.10.20.120:4455Fimeg/Pixel3Arch + Fimeg/linux-blueline (branch blueline) Source of truth. Uncommitted work does not build — commit or it doesn't exist.
ArchDev LXC casey@10.10.20.123 (ani key) Build host. Cross toolchain installed, MAKEFLAGS system-wide.
Laptop Device ops only — flashing, fastboot, USB tether, boot.img assembly.

The loop

  1. Commit + push kernel changes to gitea (kernel/src/linux-blueline-src on the laptop is a clone with remote gitea).
  2. Build on ArchDev: ssh ... casey@10.10.20.123 'cd ~/Projects/Pixel3Arch/kernel && ./build.sh blueline'
    • build.sh self-locks with flock — invoke it directly, never wrap it in an outer flock on the same lockfile (deadlock, cost a session).
    • It force-fresh-clones from gitea and hard-asserts the built package's embedded commit hash matches the gitea branch tip — a mismatch means stale source; the build fails loud instead of shipping it.
  3. Pull kernel/linux-blueline-7.1.1-1-aarch64.pkg.tar.zst to the laptop.
  4. Assemble the boot image (pmOS-chain — the currently proven ramdisk path):
    bash boot/build-bootimg-pmos-chain.sh <vmlinuz-from-pkg> <dtb-from-pkg> \
         staging/deploy-139aa/boot-139aa7748181-pmoschain.img <out.img>
    
    Kernel is Image.gz + appended DTB (header v0 ignores --dtb); ramdisk and cmdline are lifted from the reference image. Migrating to our own mkinitcpio ramdisk (boot/build-bootimg.sh) is a parked one-variable task.
  5. Deploy: scripts/deploy-kernel.sh <pkg.tar.zst> <boot.img>

Deploy doctrine — no chimera boots

deploy-kernel.sh exists because a kernel was once booted 28 seconds before its module tree was installed: no evdev, no input, dead services, and a night of void test results. The script enforces the only safe order:

  1. Modules first — scp the pkg, pacman -U, verify the module dir exists.
  2. Flash boot_a, reboot.
  3. Refuse to bless the boot unless uname -r matches the installed tree.

Never flash-then-install. If uname -r and /usr/lib/modules/ disagree, every test result on that boot is garbage — reboot properly before concluding anything.

Gotchas ledger (each cost a session)

  • makepkg needs CARCH=aarch64 ... --ignorearch — CARCH comes from the environment, not the PKGBUILD, or you get x86_64-labeled aarch64 packages.
  • makepkg builds in its own clone of source=(), not your working tree — a dirty tree silently builds without your changes.
  • The kernel release string embeds the git hash (-g<hash>) — it is the ground truth for "what am I actually running" (uname -r).
  • modules_install needs CROSS_COMPILE too, or strip fails on aarch64 .ko.
  • ArchDev is unprivileged LXC: qemu-emulated execution (binfmt) does NOT work there — chroot-based work stays on the laptop or on-device.
  • Commit messages: history in this repo proved that "evidence" cited in rapid-fire commits can be wrong (see touch.md, display.md post-mortems). Cite the actual file:line / register / boot you verified on, and note whether the boot was clean.