ReviewOS

home-lang/home-os

A6.2: `home build --kernel --target=aarch64-freestanding` — explicit target selection, ELF64/aarch64 object emission, relocations, cross-compile from macOS/x86 CI

#52
Open chris opened this 9 days ago ·
9 days ago

Epic: #113 · Milestone: MC1 — Toolchain: aarch64

Why

src/main.zig picks the backend from the host CPU (builtin.target.cpu.arch == .aarch64 → arm64 path, else x86). --target is parsed (L2895–2909) but the kernel path ignores it. packages/build/src/cross_compilation.zig already models Arch{x86_64, aarch64, …} and Target.parse("aarch64-linux-gnu"), and packages/build/src/linker_arm64.ld exists — none of it is wired to home build --kernel. CI runs on x86 ubuntu-latest, so cross-compilation is mandatory, not optional.

Tasks

  • Wire --target=<arch>-freestanding into the --kernel path; default = host; reject unknown.
  • Emit assembly the assembler for that arch accepts (zig cc -c -x assembler -target aarch64-freestanding, matching how scripts/build.sh already drives x86) and/or direct ELF64 EM_AARCH64 objects via packages/codegen/src/elf.zig (which already has .aarch64), with R_AARCH64_ADR_PREL_PG_HI21 / ADD_ABS_LO12_NC / CALL26 relocations.
  • Section discipline the Pi linker script needs: .text.boot first, .rodata, .data, .bss with __bss_start/__bss_end, 4 KB alignment for page tables (align(4096) in Home → .balign 4096).
  • home build --kernel --target=aarch64-freestanding --emit=asm|obj documented in the compiler README; add aarch64-freestanding to the compiler's CI matrix (x86 host cross-assembling, no runner change).
  • Bump HOME_COMPILER_REF in .github/workflows/ci.yml once landed.

Acceptance

On an x86 Linux CI runner and on an Apple-Silicon Mac, the same command produces a byte-identical aarch64 ELF for rung 1 of #51, and readelf -h shows AArch64.

Size: M · Depends on: #51 (rung 1) · Blocks: #54

9 days ago

Compiler-side work mirrored to home-lang/home#583.

9 days ago

Landed: --target for the kernel path

home-lang/home@29b9eb740.

  • home build <file> --kernel --target=aarch64-freestanding now selects the architecture. Arch.parseTriple accepts aarch64, arm64, aarch64-freestanding, aarch64-linux-gnu, x86_64-*, and x86-64-*. It is written as a prefix match rather than a split on -, because the architecture is itself sometimes spelled with a dash, which a split would truncate to x86. aarch64be-* is rejected rather than silently accepted as little-endian.
  • Default is x86-64, not the host. An earlier draft defaulted to the host architecture and immediately broke this machine: the host is Apple Silicon, so every existing build.sh invocation started emitting aarch64 while the script still assembled it as x86. A freestanding kernel is always a cross-compile, so the host says nothing about the target; the established default is preserved and reaching another architecture is explicit.
  • --target validation is now split by mode. It named a JavaScript runtime (browser/bun/node) and rejected everything else, so --kernel --target=aarch64-freestanding failed with expected browser, bun, or node. The two vocabularies are disjoint, and which applies is decided by --kernel. A bad kernel triple gets its own diagnostic naming the supported ones.

Still open in this issue

  • Direct ELF64 EM_AARCH64 object emission with R_AARCH64_* relocations. Currently the path is assembly out, then zig cc -c -x assembler -target aarch64-freestanding, which is exactly how the x86 path already works in scripts/build.sh — so this is not blocking, but the issue's scope includes it.
  • Section discipline for the Pi linker script (.text.boot first, __bss_start/__bss_end).
  • Adding aarch64-freestanding to this repo's CI matrix.

Sign in to comment on this issue.