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)"