← board

FreeBSD native target (amd64) — raw-syscall, stays in the libc-free family

Why FreeBSD is the cheapest first win

Same family as Linux: raw-syscall ELF on amd64, identical argument registers (rdi/rsi/rdx/r10/r8/r9). Keeps the libc-free identity intact. And FreeBSD's linuxulator (linux64.ko) runs today's Linux pxx binaries unmodified — a zero-work smoke on a real BSD kernel before writing a line of code.

What differs from Linux (the whole delta)

  1. Syscall numbers — FreeBSD's own table (write=4, exit=1, …), not Linux's.
  2. Error convention — FreeBSD signals an error via the carry flag (CF set, errno in rax), NOT Linux's negative-rax. This is the real work — every syscall wrapper's error check changes, not just a number swap.
  3. ELF brand — set EI_OSABI = ELFOSABI_FREEBSD (9) or emit the NT_FREEBSD_ABI_TAG note so the kernel brands the binary correctly.
  4. exit_groupexit (no thread-group exit; adjust the process-exit path).

Plan

Acceptance

Test infra

qemu FreeBSD image (FreeBSD.org publishes pre-built qcow2 VM images, unlike OpenBSD — cf. the parallel line in [[feature-port-openbsd-libc]], "qemu OpenBSD via autoinstall (no pre-built qcow2)", filed in the same commit) + linuxulator. The per-OS image/runner harness may live in a Track T clone (see portability-axes.md) — the compiler work is here.

Wording clarified 2026-08-28 by Track T (pxx-a5). This line previously read "(pre-built qcow2 exists)" and was read below, and in [[feature-t-freebsd-image-and-runner]], as a claim that an image existed on our infrastructure. It never said that: it is one half of an obtain-the-image comparison with OpenBSD. The sentence was true; its subject was upstream. Nothing about the plan changed — only the reading it invites.

2026-08-20 — not started: the test infra this needs is not on plexus

Reached as the top Track A item and deliberately not claimed. The blocker is environmental, not a design question, so it is recorded here rather than escalated to Track U.

Measured on plexus (the dev box, frank1):

Resolved 2026-08-28 by Track T (pxx-a5): neither. Re-measured on plexus (nothing changed in eight days — no qemu-system-* of any kind, no libvirt, no *.qcow2 / *.iso / *.img anywhere reachable). The claim is not stale and not about another box: it is a true statement about what FreeBSD.org publishes, misread as an inventory. See the clarified wording above and [[feature-t-freebsd-image-and-runner]] for the full measurement. The practical consequence is unchanged — there is still no kernel to boot here, and this ticket stays blocked — but the lead "go find the existing image" is closed, and nobody should spend time on it again.

Both acceptance criteria are unrunnable here: the native --platform=freebsd run and the linuxulator smoke need a FreeBSD kernel. The ticket's own plan puts that smoke first, ahead of writing any code, which is the right order — it is the cheap proof that the ELF layout is already acceptable to the kernel.

Why the verifiable subset was not landed either

Two of the four deltas could be written and partially checked without FreeBSD — the syscall-number table, and the ELF brand (EI_OSABI = 9, assertable straight out of the emitted header). The third cannot: the carry-flag error convention is the item this ticket itself calls "the real work", it touches every syscall wrapper's error check, and nothing on this box can tell a correct carry-flag path from a wrong one.

Landing the easy two would leave a --platform=freebsd that emits a correctly-branded ELF whose every syscall error check is untested — a half-applied Track A change, which CLAUDE.md flags as the critical case because it is the shape that quietly poisons the shared ground. Better an unstarted ticket than a platform that looks present and is not.

What unblocks it: qemu plus a FreeBSD/amd64 image on whichever box runs it, or confirmation of where the existing qcow2 lives. That is Track T-shaped infrastructure work (per portability-axes.md, the per-OS image/runner harness may live in a Track T clone); the compiler work here is ready to start the moment a kernel is reachable.