boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

Kit0 integration

boot2 can compile a prepared Kit bootstrap profile as separate translation units and link the resulting P1pp through its ordinary per-architecture P1/M1pp/hex2pp path. The supported boot2 architecture names are aarch64, amd64, and riscv64; RV32 has no corresponding Kit0 profile. Kit currently supplies the aa64 preparation; the x64 and rv64 mappings are ready for the corresponding profiles when they are added.

Prepare and check from the Kit worktree:

cd ../../kit
gmake bootstrap-aa64-prepare
KIT0_SWEEP_JOBS=2 gmake bootstrap-aa64-check

Or run only the boot2 link from this worktree:

gmake ARCH=aarch64 DRIVER=podman \
  KIT0_PREP="$(cd ../../kit && pwd)/build/bootstrap-aa64/kit0-prep" kit0
podman run --rm --pull=never --platform linux/arm64 \
  -v "$(pwd):/boot2" -w /boot2 boot2-busybox-test:aarch64 \
  /boot2/build/aarch64/podman/kit0/kit0 --version

When KIT0_PREP is omitted, the Makefile maps boot2 architecture names to the conventional Kit profile suffixes: aarch64 to aa64, amd64 to x64, and riscv64 to rv64. KIT_DIR defaults to ../../kit, KIT0_PROFILE can override just the profile suffix, and an explicit KIT0_PREP can point anywhere. The selected preparation must enable the matching KIT_ARCH_*_ENABLED setting in resolved-config.h; this prevents accidentally framing, assembling, or running one target's prepared sources as another target.

boot/kit0.sh validates the prepared manifest.tsv, resolved-config.h, and m1pp-partitions.tsv, then imports the preprocessed tu/*.i files and kit0-run.scm. The partition manifest is the inspectable record of the order encoded in that recipe. The recipe compiles mes-libc and each Kit TU separately. It expands the M1pp runtime once, then independently expands entry, libc, every Kit TU, and the ELF terminator by replaying the common macro prelude and using %reset-output with disjoint hygiene-label ranges. Each non-runtime partition begins with .align 16. The ordered hex2pp partitions are concatenated, prefixed with the ELF framing, and assembled by the existing hex2pp stage. It does not copy generated Kit inputs into this worktree.

General cc.scm additions

Kit0 exposed a few ordinary C gaps. They are implemented without Kit source or filename special cases:

The intentionally bootstrap-level behavior is documented in docs/CC.md: _Noreturn carries no metadata, and _Alignas accepts only the universally layout-neutral zero or one/char requests because P1's seed object layout cannot represent over-alignment. Kit's prepared implementation TUs contain no live _Alignas declarations; the focused fixture exercises this no-op contract.

Focused regression tests

Run the compatibility cases across all four boot2 architectures:

tests/run.sh --suite cc \
  320-vararg-cap 346-c11-decl-align 347-aggregate-indirect-arg \
  348-unsigned-div-rem 349-aggregate-indirect-lvalue-arg \
  350-large-aggregate-flow 351-address-of-member-local \
  352-aggregate-compound-call 353-static-local-scope-collision
tests/run.sh --suite cc-util 015-lib-static-namespace
tests/run.sh --suite m1pp 032-reset-output

The first fixture exercises a 20-argument call above the former variadic window. The declaration fixture covers every added declaration/alignment form plus both offsetof contexts, nested designators, and grouped aggregate compound initialization. The aggregate fixture checks that a callee may mutate a large by-value argument without changing its source object. The additional aggregate fixtures cover indirect member lvalues and nested whole-aggregate flow. The arithmetic fixture checks unsigned quotient and remainder boundary cases. The address fixture protects the unevaluated snapshot invariant. The compound-call fixture checks both the two-word argument shape and local string-literal sizeof; the static-local fixture checks same-spelling declarations in distinct scopes. The utility fixture checks every non-function-local label family under --lib; the M1pp fixture checks output reset and hygiene-base selection.

The Kit-side check then supplies the integration coverage: every selected TU must translate, the entire P1 set must link with mes-libc, the resulting Kit0 must run for the selected architecture, and that seed-built compiler must emit and archive target objects and statically link a representative executable.