boot2

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

prep-src.sh (10475B)


      1 #!/bin/sh
      2 ## prep-src.sh — build the canonical generated source tree.
      3 ##
      4 ## All host-side source preparation happens once, up front, into a
      5 ## single canonical tree at build/<arch>/src/. This tree is the audit
      6 ## basis and the only thing boot stages should read for source. Boot
      7 ## stages do no flattening, no unpacking, no patching, no calibration.
      8 ##
      9 ## Layout produced:
     10 ##   build/<arch>/src/
     11 ##     bin/                      binary inputs not built by a stage
     12 ##       hex0-seed                 vendored seed only
     13 ##     src/                      everything textual
     14 ##       stage0-posix/              ELF.hex2 + *.hex0|*.hex1|*.hex2
     15 ##       M1pp/                     M1pp.P1
     16 ##       hex2pp/                   hex2pp.P1
     17 ##       P1/                       P1*.{M1,M1pp,P1pp}, entry-*.P1pp,
     18 ##                                   elf-end.P1pp
     19 ##       catm/                     catm.P1pp
     20 ##       scheme1/                  scheme1.P1pp, prelude.scm
     21 ##       cc/                       cc.scm, main.scm
     22 ##       tcc/                      tcc.flat.c, stdarg-bridge.h, plus
     23 ##                                   tcc-0.9.26-1147-gee75a10c/{include,lib}
     24 ##       tcc/libc/$ARCH/           start.S, sys_stubs.S
     25 ##       tcc/cc/                   mem.c (memcpy/memmove/memset/memcmp)
     26 ##       libc/                     libc.flat.c (mes-libc flattened)
     27 ##       musl/                     filtered musl-1.2.5 tree (overrides
     28 ##                                   merged, deletes applied, generated
     29 ##                                   alltypes.h/syscall.h dropped in,
     30 ##                                   per-arch skip filter applied).
     31 ##       kernel/                   seed-kernel sources for this arch
     32 ##       test-fixtures/            boot-hello.c smoke binary
     33 ##     run/                      run.scm files driving each bootN stage
     34 ##       boot3.scm                 static (copied from bootprep/assets/)
     35 ##       boot4.scm                 generated by bootprep/boot4-gen-runscm.sh
     36 ##       boot5.scm                 generated by bootprep/boot5-gen-runscm.sh
     37 ##       boot6.scm                 generated by bootprep/boot6-gen-runscm.sh
     38 ##
     39 ## The musl skip list (vendor/musl/skip-<arch>.txt) is calibrated
     40 ## offline by bootprep/boot5-calibrate.sh and committed; prep-src.sh
     41 ## reads it and applies the filter inline. Re-run boot5-calibrate.sh
     42 ## manually when the patch set, calibration arch, or tcc version
     43 ## changes.
     44 ##
     45 ## Usage: bootprep/prep-src.sh <arch>
     46 ##   <arch> ∈ {aarch64, amd64, riscv64}
     47 
     48 set -eu
     49 
     50 . boot/lib-arch.sh
     51 bootlib_init prep-src "${1:-}"
     52 
     53 DST=$ROOT/build/$ARCH/src
     54 DST_BIN=$DST/bin
     55 DST_SRC=$DST/src
     56 
     57 TAG="[$BOOT_TAG]"
     58 
     59 # ── (0) reset destination ─────────────────────────────────────────────
     60 rm -rf "$DST"
     61 mkdir -p "$DST_BIN" "$DST_SRC"
     62 
     63 # ── (1) vendored seed (pre-built binary + textual sources) ────────────
     64 SEED=vendor/seed/$ARCH
     65 [ -d "$SEED" ] || { echo "$TAG missing $SEED" >&2; exit 1; }
     66 
     67 cp "$SEED/hex0-seed" "$DST_BIN/hex0-seed"
     68 
     69 mkdir -p "$DST_SRC/stage0-posix"
     70 for f in ELF.hex2 hex0.hex0 hex1.hex0 hex2.hex1 catm.hex2 M0.hex2; do
     71     [ -e "$SEED/$f" ] || { echo "$TAG missing $SEED/$f" >&2; exit 1; }
     72     cp "$SEED/$f" "$DST_SRC/stage0-posix/$f"
     73 done
     74 
     75 # ── (2) repo-tree textual sources ─────────────────────────────────────
     76 mkdir -p "$DST_SRC/M1pp"
     77 cp M1pp/M1pp.P1                 "$DST_SRC/M1pp/M1pp.P1"
     78 
     79 mkdir -p "$DST_SRC/hex2pp"
     80 cp hex2pp/hex2pp.P1             "$DST_SRC/hex2pp/hex2pp.P1"
     81 
     82 mkdir -p "$DST_SRC/P1"
     83 cp "P1/P1.M1pp"                 "$DST_SRC/P1/P1.M1pp"
     84 cp "P1/P1-$ARCH.M1"             "$DST_SRC/P1/P1-$ARCH.M1"
     85 cp "P1/P1-$ARCH.M1pp"           "$DST_SRC/P1/P1-$ARCH.M1pp"
     86 cp "P1/P1pp.P1pp"               "$DST_SRC/P1/P1pp.P1pp"
     87 cp "P1/entry-libc.P1pp"         "$DST_SRC/P1/entry-libc.P1pp"
     88 cp "P1/entry-plain.P1pp"        "$DST_SRC/P1/entry-plain.P1pp"
     89 cp "P1/elf-end.P1pp"            "$DST_SRC/P1/elf-end.P1pp"
     90 
     91 mkdir -p "$DST_SRC/catm"
     92 cp catm/catm.P1pp               "$DST_SRC/catm/catm.P1pp"
     93 
     94 mkdir -p "$DST_SRC/scheme1"
     95 cp scheme1/scheme1.P1pp         "$DST_SRC/scheme1/scheme1.P1pp"
     96 cp scheme1/prelude.scm          "$DST_SRC/scheme1/prelude.scm"
     97 
     98 mkdir -p "$DST_SRC/cc"
     99 cp cc/cc.scm                    "$DST_SRC/cc/cc.scm"
    100 cp cc/main.scm                  "$DST_SRC/cc/main.scm"
    101 
    102 # tcc-libc: per-arch _start + sys_* wrappers consumed by boot4.
    103 mkdir -p "$DST_SRC/tcc/libc/$ARCH"
    104 cp "tcc/libc/$ARCH/start.S"     "$DST_SRC/tcc/libc/$ARCH/start.S"
    105 cp "tcc/libc/$ARCH/sys_stubs.S" "$DST_SRC/tcc/libc/$ARCH/sys_stubs.S"
    106 
    107 # tcc-cc: tiny mem helpers consumed by boot4 + boot6.
    108 mkdir -p "$DST_SRC/tcc/cc"
    109 cp tcc/cc/mem.c                 "$DST_SRC/tcc/cc/mem.c"
    110 
    111 # Smoke binary linked by boot4 + boot5.
    112 mkdir -p "$DST_SRC/test-fixtures"
    113 cp bootprep/assets/boot-hello.c "$DST_SRC/test-fixtures/boot-hello.c"
    114 
    115 # ── (3) seed-kernel sources for this arch ─────────────────────────────
    116 mkdir -p "$DST_SRC/kernel/arch/$ARCH" "$DST_SRC/kernel/user"
    117 cp seed-kernel/kernel.c                     "$DST_SRC/kernel/kernel.c"
    118 for f in seed-kernel/arch/$ARCH/*; do
    119     [ -f "$f" ] || continue
    120     cp "$f" "$DST_SRC/kernel/arch/$ARCH/$(basename "$f")"
    121 done
    122 for f in seed-kernel/user/*; do
    123     [ -f "$f" ] || continue
    124     cp "$f" "$DST_SRC/kernel/user/$(basename "$f")"
    125 done
    126 
    127 # ── (4) tcc flatten ───────────────────────────────────────────────────
    128 # stage1-flatten.sh writes to build/<arch>/vendor/tcc/. Run it (it's
    129 # idempotent) and mirror the relevant artifacts into src/tcc/.
    130 echo "$TAG flatten tcc.flat.c (host)"
    131 bootprep/stage1-flatten.sh --arch "$ARCH"
    132 
    133 TCC_VENDOR=$ROOT/build/$ARCH/vendor/tcc
    134 TCC_PKG=tcc-0.9.26-1147-gee75a10c
    135 [ -e "$TCC_VENDOR/tcc.flat.c"          ] || { echo "$TAG flatten produced no tcc.flat.c" >&2; exit 1; }
    136 [ -e "$TCC_VENDOR/stdarg-bridge.h"     ] || { echo "$TAG flatten produced no stdarg-bridge.h" >&2; exit 1; }
    137 [ -d "$TCC_VENDOR/$TCC_PKG/include"    ] || { echo "$TAG flatten produced no $TCC_PKG/include" >&2; exit 1; }
    138 [ -d "$TCC_VENDOR/$TCC_PKG/lib"        ] || { echo "$TAG flatten produced no $TCC_PKG/lib" >&2; exit 1; }
    139 
    140 mkdir -p "$DST_SRC/tcc"
    141 cp "$TCC_VENDOR/tcc.flat.c"        "$DST_SRC/tcc/tcc.flat.c"
    142 cp "$TCC_VENDOR/stdarg-bridge.h"   "$DST_SRC/tcc/stdarg-bridge.h"
    143 mkdir -p "$DST_SRC/tcc/$TCC_PKG"
    144 cp -R "$TCC_VENDOR/$TCC_PKG/include" "$DST_SRC/tcc/$TCC_PKG/include"
    145 cp -R "$TCC_VENDOR/$TCC_PKG/lib"     "$DST_SRC/tcc/$TCC_PKG/lib"
    146 
    147 # ── (5) mes-libc flatten ──────────────────────────────────────────────
    148 echo "$TAG flatten libc.flat.c (host)"
    149 bootprep/libc-flatten.sh --arch "$ARCH"
    150 
    151 LIBC_VENDOR=$ROOT/build/$ARCH/vendor/mes-libc
    152 [ -e "$LIBC_VENDOR/libc.flat.c" ] || { echo "$TAG flatten produced no libc.flat.c" >&2; exit 1; }
    153 
    154 mkdir -p "$DST_SRC/libc"
    155 cp "$LIBC_VENDOR/libc.flat.c"      "$DST_SRC/libc/libc.flat.c"
    156 
    157 # ── (6) musl unpack + overrides + deletes + generated headers ─────────
    158 MUSL_TARBALL=vendor/musl/1.2.5.tar.gz
    159 MUSL_OVERRIDES=vendor/musl/overrides
    160 MUSL_DELETES=vendor/musl/deletes.txt
    161 MUSL_GENERATED=vendor/musl/generated/$MUSL_ARCH
    162 MUSL_SKIP=vendor/musl/skip-$ARCH.txt
    163 
    164 [ -e "$MUSL_TARBALL"   ] || { echo "$TAG missing $MUSL_TARBALL" >&2; exit 1; }
    165 [ -d "$MUSL_OVERRIDES" ] || { echo "$TAG missing $MUSL_OVERRIDES" >&2; exit 1; }
    166 [ -e "$MUSL_DELETES"   ] || { echo "$TAG missing $MUSL_DELETES" >&2; exit 1; }
    167 [ -d "$MUSL_GENERATED" ] || { echo "$TAG missing $MUSL_GENERATED (run bootprep/musl-vendor.sh)" >&2; exit 1; }
    168 [ -e "$MUSL_SKIP"      ] || { echo "$TAG missing $MUSL_SKIP (run bootprep/boot5-calibrate.sh $ARCH)" >&2; exit 1; }
    169 
    170 echo "$TAG unpack musl-1.2.5 + apply overrides/deletes"
    171 MUSL_TMP=$(mktemp -d)
    172 trap 'rm -rf "$MUSL_TMP"' EXIT
    173 tar xzf "$MUSL_TARBALL" -C "$MUSL_TMP"
    174 [ -d "$MUSL_TMP/musl-1.2.5" ] || { echo "$TAG musl tarball did not unpack to musl-1.2.5/" >&2; exit 1; }
    175 
    176 cp -R "$MUSL_OVERRIDES/." "$MUSL_TMP/musl-1.2.5/"
    177 while read -r p; do
    178     [ -n "$p" ] && rm -rf "$MUSL_TMP/musl-1.2.5/$p"
    179 done < "$MUSL_DELETES"
    180 
    181 # Drop pre-generated arch headers + version.h into the same obj/ layout
    182 # boot5 expects.
    183 mkdir -p "$MUSL_TMP/musl-1.2.5/obj/include/bits" \
    184          "$MUSL_TMP/musl-1.2.5/obj/src/internal"
    185 cp "$MUSL_GENERATED/alltypes.h" "$MUSL_TMP/musl-1.2.5/obj/include/bits/alltypes.h"
    186 cp "$MUSL_GENERATED/syscall.h"  "$MUSL_TMP/musl-1.2.5/obj/include/bits/syscall.h"
    187 echo '#define VERSION "1.2.5-tcc-boot5"' > "$MUSL_TMP/musl-1.2.5/obj/src/internal/version.h"
    188 
    189 mkdir -p "$DST_SRC/musl"
    190 # Move into place — the canonical tree owns this from now on.
    191 ( cd "$MUSL_TMP/musl-1.2.5" && tar cf - . ) | ( cd "$DST_SRC/musl" && tar xf - )
    192 
    193 # Apply the committed per-arch skip filter inline: copy the list as
    194 # skip.txt metadata, then drop every listed path from src/musl/.
    195 cp "$MUSL_SKIP" "$DST_SRC/musl/skip.txt"
    196 n_skip=0
    197 n_missing=0
    198 while read -r rel; do
    199     [ -n "$rel" ] || continue
    200     case "$rel" in
    201         \#*) continue ;;
    202     esac
    203     if [ -e "$DST_SRC/musl/$rel" ]; then
    204         rm -rf "$DST_SRC/musl/$rel"
    205         n_skip=$((n_skip + 1))
    206     else
    207         n_missing=$((n_missing + 1))
    208     fi
    209 done < "$DST_SRC/musl/skip.txt"
    210 if [ "$n_missing" -gt 0 ]; then
    211     echo "$TAG WARN: $n_missing skip-list entries were not present in $DST_SRC/musl" >&2
    212 fi
    213 echo "$TAG musl skip filter: dropped=$n_skip"
    214 
    215 # ── (7) run.scm files ─────────────────────────────────────────────────
    216 # Static run.scm (boot3) copied verbatim; the rest are generated. The
    217 # musl tree is now stable, so boot5-enumerate + boot5-gen-runscm can
    218 # run alongside boot4/boot6 generation.
    219 mkdir -p "$DST/run"
    220 cp bootprep/assets/boot3-run.scm "$DST/run/boot3.scm"
    221 bootprep/boot4-gen-runscm.sh "$ARCH"
    222 bootprep/boot5-enumerate.sh "$ARCH"
    223 bootprep/boot5-gen-runscm.sh "$ARCH"
    224 bootprep/boot6-gen-runscm.sh "$ARCH"
    225 
    226 # ── summary ───────────────────────────────────────────────────────────
    227 n_files=$(find "$DST" -type f | wc -l | tr -d ' ')
    228 echo "$TAG OK -> $DST  ($n_files files)"