boot2

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

commit b53d0180d693b167bcae99b7dbc5249b47b35be0
parent 7eb6f0aca7c2e70dc13a72a3be5b46f6de5ff588
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Tue,  5 May 2026 18:55:20 -0700

boot6: rename output kernel.elf -> Image

The file is a flat arm64 boot Image (since `-Wl,--oformat=binary`),
not ELF, so the `.elf` extension was misleading.  `Image` matches
the gcc Makefile's `seed-kernel/build/Image` convention and the
arm64 Linux upstream name.

Updates every consumer in lockstep: boot{0..5}.sh's
`KERNEL_IMAGE=`, boot.sh's stash filename, seed-accept{,-boot34,
-boot5}.sh's `KERNEL=`, and the boot6 docstring + run.scm output
target.  Full `DRIVER=seed boot.sh aarch64` re-validated (98s).

Diffstat:
Mdocs/OS-TODO.md | 16+++++-----------
Mscripts/boot.sh | 14+++++++-------
Mscripts/boot0.sh | 2+-
Mscripts/boot1.sh | 2+-
Mscripts/boot2.sh | 2+-
Mscripts/boot3.sh | 2+-
Mscripts/boot4.sh | 2+-
Mscripts/boot5.sh | 2+-
Mscripts/boot6-gen-runscm.sh | 6+++---
Mscripts/boot6.sh | 19+++++++++++--------
Mscripts/seed-accept-boot34.sh | 4++--
Mscripts/seed-accept-boot5.sh | 4++--
Mscripts/seed-accept.sh | 2+-
13 files changed, 37 insertions(+), 40 deletions(-)

diff --git a/docs/OS-TODO.md b/docs/OS-TODO.md @@ -20,19 +20,13 @@ kernel.lds`, no objcopy. The link line is just three flags: tcc3 -nostdlib -static \ -Wl,-Ttext=0x40080000 \ -Wl,--oformat=binary \ - -o kernel.elf kernel.S.o kernel.c.o mem.c.o + -o Image kernel.S.o kernel.c.o mem.c.o ``` +The output (`build/aarch64/boot6/Image`) is byte-format identical in +shape to the gcc Makefile's `objcopy -O binary` flat Image: +[`seed-kernel/build/Image`](../seed-kernel/Makefile). + `DRIVER=seed scripts/boot.sh aarch64` runs the entire boot0→boot6 pipeline (including a re-run of boot6 itself) on top of the tcc3-built kernel, closing the self-host loop at the OS layer. - -This file tracks remaining polish. - -## boot6 output filename - -[`scripts/boot6.sh`](../scripts/boot6.sh) writes its output to -`build/aarch64/boot6/kernel.elf`, but with `--oformat=binary` the -file is a flat arm64 boot Image, not ELF. Misleading; rename to -`Image` (matching `seed-kernel/build/Image` from the gcc Makefile) -and update boot{0..5}.sh's `KERNEL_IMAGE=` to follow. diff --git a/scripts/boot.sh b/scripts/boot.sh @@ -6,12 +6,12 @@ ## DRIVER=podman scripts/boot.sh <amd64|aarch64|riscv64> ## ## DRIVER (default podman) is exported and consumed by each bootN.sh. -## DRIVER=seed is aarch64-only and runs on build/$ARCH/boot6/kernel.elf — +## DRIVER=seed is aarch64-only and runs on build/$ARCH/boot6/Image — ## the tcc3-built seed kernel produced by boot6. First-time setup ## therefore requires one prior podman pass to produce that kernel: ## ./scripts/boot.sh aarch64 # default DRIVER=podman ## DRIVER=seed ./scripts/boot.sh aarch64 # re-run on tcc-built kernel -## Subsequent DRIVER=seed runs reuse the kernel.elf from the prior boot6 +## Subsequent DRIVER=seed runs reuse the Image from the prior boot6 ## (stashed across the build/$ARCH wipe below). set -e @@ -22,9 +22,9 @@ DRIVER=${DRIVER:-podman} case "$DRIVER" in seed) [ "$ARCH" = aarch64 ] || { echo "[boot] DRIVER=seed: aarch64 only" >&2; exit 2; } - KERNEL_ELF=build/$ARCH/boot6/kernel.elf - if [ ! -f "$KERNEL_ELF" ]; then - echo "[boot] DRIVER=seed: missing $KERNEL_ELF" >&2 + KERNEL=build/$ARCH/boot6/Image + if [ ! -f "$KERNEL" ]; then + echo "[boot] DRIVER=seed: missing $KERNEL" >&2 echo "[boot] run './scripts/boot.sh $ARCH' first (default DRIVER=podman) to produce it" >&2 exit 1 fi @@ -32,7 +32,7 @@ case "$DRIVER" in # below; restored before stage 0 runs. STASH=build/.seed-bootstrap/$ARCH mkdir -p "$STASH" - cp "$KERNEL_ELF" "$STASH/kernel.elf" + cp "$KERNEL" "$STASH/Image" ;; podman) ;; *) echo "[boot] unknown DRIVER=$DRIVER (expected podman|seed)" >&2; exit 2 ;; @@ -43,7 +43,7 @@ rm -rf build/$ARCH if [ "$DRIVER" = seed ]; then mkdir -p build/$ARCH/boot6 - cp build/.seed-bootstrap/$ARCH/kernel.elf build/$ARCH/boot6/kernel.elf + cp build/.seed-bootstrap/$ARCH/Image build/$ARCH/boot6/Image fi T0=$(date +%s) diff --git a/scripts/boot0.sh b/scripts/boot0.sh @@ -48,7 +48,7 @@ case "$DRIVER" in export PLATFORM IMAGE ;; seed) [ "$ARCH" = "aarch64" ] || { echo "[boot0] DRIVER=seed: aarch64 only" >&2; exit 2; } - KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/kernel.elf + KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/Image EXTRACT=$ROOT/seed-kernel/scripts/extract-blk.sh [ -f "$KERNEL_IMAGE" ] || { echo "[boot0] missing $KERNEL_IMAGE — run ./scripts/boot.sh $ARCH (default DRIVER=podman) first" >&2; exit 1; } export KERNEL_IMAGE EXTRACT ;; diff --git a/scripts/boot1.sh b/scripts/boot1.sh @@ -58,7 +58,7 @@ case "$DRIVER" in export PLATFORM IMAGE ;; seed) [ "$ARCH" = "aarch64" ] || { echo "[boot1] DRIVER=seed: aarch64 only" >&2; exit 2; } - KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/kernel.elf + KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/Image EXTRACT=$ROOT/seed-kernel/scripts/extract-blk.sh [ -f "$KERNEL_IMAGE" ] || { echo "[boot1] missing $KERNEL_IMAGE — run ./scripts/boot.sh $ARCH (default DRIVER=podman) first" >&2; exit 1; } export KERNEL_IMAGE EXTRACT ;; diff --git a/scripts/boot2.sh b/scripts/boot2.sh @@ -66,7 +66,7 @@ case "$DRIVER" in export PLATFORM IMAGE ;; seed) [ "$ARCH" = "aarch64" ] || { echo "[boot2] DRIVER=seed: aarch64 only" >&2; exit 2; } - KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/kernel.elf + KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/Image EXTRACT=$ROOT/seed-kernel/scripts/extract-blk.sh [ -f "$KERNEL_IMAGE" ] || { echo "[boot2] missing $KERNEL_IMAGE — run ./scripts/boot.sh $ARCH (default DRIVER=podman) first" >&2; exit 1; } export KERNEL_IMAGE EXTRACT ;; diff --git a/scripts/boot3.sh b/scripts/boot3.sh @@ -85,7 +85,7 @@ if [ "$DRIVER" = podman ] && ! podman image exists "$IMAGE"; then fi if [ "$DRIVER" = seed ]; then [ "$ARCH" = aarch64 ] || { echo "[boot3] DRIVER=seed: aarch64 only" >&2; exit 2; } - KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/kernel.elf + KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/Image EXTRACT=$ROOT/seed-kernel/scripts/extract-blk.sh [ -f "$KERNEL_IMAGE" ] || { echo "[boot3] missing $KERNEL_IMAGE — run ./scripts/boot.sh $ARCH (default DRIVER=podman) first" >&2; exit 1; } export KERNEL_IMAGE EXTRACT diff --git a/scripts/boot4.sh b/scripts/boot4.sh @@ -121,7 +121,7 @@ if [ "$DRIVER" = podman ] && ! podman image exists "$IMAGE"; then fi if [ "$DRIVER" = seed ]; then [ "$ARCH" = aarch64 ] || { echo "[boot4] DRIVER=seed: aarch64 only" >&2; exit 2; } - KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/kernel.elf + KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/Image EXTRACT=$ROOT/seed-kernel/scripts/extract-blk.sh [ -f "$KERNEL_IMAGE" ] || { echo "[boot4] missing $KERNEL_IMAGE — run ./scripts/boot.sh $ARCH (default DRIVER=podman) first" >&2; exit 1; } export KERNEL_IMAGE EXTRACT diff --git a/scripts/boot5.sh b/scripts/boot5.sh @@ -103,7 +103,7 @@ if [ "$DRIVER" = podman ] && ! podman image exists "$IMAGE"; then -f scripts/Containerfile.empty scripts/ fi if [ "$DRIVER" = seed ]; then - KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/kernel.elf + KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/Image EXTRACT=$ROOT/seed-kernel/scripts/extract-blk.sh [ -f "$KERNEL_IMAGE" ] || { echo "[boot5] missing $KERNEL_IMAGE — run ./scripts/boot.sh $ARCH (default DRIVER=podman) first" >&2; exit 1; } export KERNEL_IMAGE EXTRACT diff --git a/scripts/boot6-gen-runscm.sh b/scripts/boot6-gen-runscm.sh @@ -71,13 +71,13 @@ cat > "$OUT" <<EOF (must (run "in/tcc3" $KCFLAGS "-c" "-o" "out/mem.o" "in/mem.c") "mem.c -> mem.o") -(write-string stdout "boot6: tcc3 link kernel.elf (flat Image)\n") +(write-string stdout "boot6: tcc3 link Image\n") (must (run "in/tcc3" "-nostdlib" "-static" "-Wl,-Ttext=0x40080000" "-Wl,--oformat=binary" - "-o" "out/kernel.elf" + "-o" "out/Image" "out/kernel-asm.o" "out/kernel.o" "out/mem.o") - "link kernel.elf") + "link Image") (write-string stdout "boot6: ALL-OK\n") (exit 0) diff --git a/scripts/boot6.sh b/scripts/boot6.sh @@ -28,11 +28,14 @@ ## kernel). Same run.scm drives both. ## ## ─── Outputs ───────────────────────────────────────────────────────── -## build/$ARCH/boot6/kernel.elf — final kernel ELF; QEMU loads its -## PT_LOAD segment at 0x40080000 and -## jumps to _head (the arm64 Image -## header), same boot path as the -## gcc-built flat Image. +## build/$ARCH/boot6/Image — flat arm64 boot Image, byte-format +## identical in shape to the gcc +## Makefile's `objcopy -O binary` +## output. QEMU's `-kernel` detects +## `ARM\x64` magic at file offset 0x38 +## and follows the arm64 boot +## protocol, putting DTB phys in x0 +## before jumping to _start. ## ## Usage: scripts/boot6.sh <arch> ## <arch>: aarch64 only. boot6 has no amd64/riscv64 analogue — the seed @@ -70,7 +73,7 @@ if [ "$DRIVER" = podman ] && ! podman image exists "$IMAGE"; then -f scripts/Containerfile.empty scripts/ fi if [ "$DRIVER" = seed ]; then - KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/kernel.elf + KERNEL_IMAGE=$ROOT/build/$ARCH/boot6/Image EXTRACT=$ROOT/seed-kernel/scripts/extract-blk.sh [ -f "$KERNEL_IMAGE" ] || { echo "[boot6] missing $KERNEL_IMAGE — run ./scripts/boot.sh $ARCH (default DRIVER=podman) first" >&2; exit 1; } export KERNEL_IMAGE EXTRACT @@ -94,7 +97,7 @@ runscm_input kernel.S seed-kernel/kernel.S runscm_input kernel.c seed-kernel/kernel.c runscm_input mem.c tcc-cc/mem.c -runscm_export kernel.elf +runscm_export Image runscm_run 1200 -echo "[boot6 $ARCH/$DRIVER] OK -> $OUT/kernel.elf ($(wc -c <"$OUT/kernel.elf") bytes)" +echo "[boot6 $ARCH/$DRIVER] OK -> $OUT/Image ($(wc -c <"$OUT/Image") bytes)" diff --git a/scripts/seed-accept-boot34.sh b/scripts/seed-accept-boot34.sh @@ -4,7 +4,7 @@ ## bootN/'s podman-built artefacts. ## ## Prereqs (build first): -## - build/aarch64/boot6/kernel.elf (run ./scripts/boot.sh aarch64 +## - build/aarch64/boot6/Image (run ./scripts/boot.sh aarch64 ## under DRIVER=podman to produce the tcc-built seed kernel) ## - build/aarch64/boot{0,1,2,3,4}/ (same boot.sh run populates these ## references) @@ -26,7 +26,7 @@ ARCH=aarch64 ROOT=$(cd "$(dirname "$0")/.." && pwd) cd "$ROOT" -KERNEL=build/$ARCH/boot6/kernel.elf +KERNEL=build/$ARCH/boot6/Image [ -f "$KERNEL" ] || { echo "missing $KERNEL — run ./scripts/boot.sh $ARCH (default DRIVER=podman) first" >&2; exit 1; } [ -x build/$ARCH/boot3/tcc0 ] || { echo "build/$ARCH/boot3/tcc0 missing — run scripts/boot3.sh aarch64" >&2; exit 1; } diff --git a/scripts/seed-accept-boot5.sh b/scripts/seed-accept-boot5.sh @@ -4,7 +4,7 @@ ## artefacts. Mirrors scripts/seed-accept-boot34.sh. ## ## Prereqs (build first): -## - build/aarch64/boot6/kernel.elf (run ./scripts/boot.sh aarch64 +## - build/aarch64/boot6/Image (run ./scripts/boot.sh aarch64 ## under DRIVER=podman to produce the tcc-built seed kernel) ## - build/aarch64/boot{0..5}/ (same boot.sh run populates these ## references) @@ -24,7 +24,7 @@ ARCH=aarch64 ROOT=$(cd "$(dirname "$0")/.." && pwd) cd "$ROOT" -KERNEL=build/$ARCH/boot6/kernel.elf +KERNEL=build/$ARCH/boot6/Image [ -f "$KERNEL" ] || { echo "missing $KERNEL — run ./scripts/boot.sh $ARCH (default DRIVER=podman) first" >&2; exit 1; } [ -d build/$ARCH/boot5 ] || { echo "build/$ARCH/boot5 missing — run scripts/boot5.sh aarch64" >&2; exit 1; } for f in libc.a crt1.o crti.o crtn.o hello; do diff --git a/scripts/seed-accept.sh b/scripts/seed-accept.sh @@ -23,7 +23,7 @@ ARCH=aarch64 ROOT=$(cd "$(dirname "$0")/.." && pwd) cd "$ROOT" -KERNEL=build/$ARCH/boot6/kernel.elf +KERNEL=build/$ARCH/boot6/Image EXTRACT=seed-kernel/scripts/extract-blk.sh SCHEME1=build/$ARCH/boot2/scheme1 CATM=build/$ARCH/boot2/catm