boot5-gen-runscm.sh (6805B)
1 #!/bin/sh 2 ## boot5-gen-runscm.sh — emit run.scm driving boot5's musl + hello build 3 ## inside the seed kernel. Mirrors scripts/boot5.sh's podman-path script 4 ## generation step-for-step: per-source `tcc -c`, per-arch CRT, archive, 5 ## link hello. Source enumeration done by boot5.sh; this script consumes 6 ## the resulting build-srcs.txt and emits one `(run "in/tcc" …)` form per TU. 7 ## 8 ## Usage: 9 ## boot5-gen-runscm.sh <musl-arch> <stage-host-dir> <out.scm> 10 ## 11 ## stage-host-dir is the boot5 _host/ directory containing: 12 ## build-srcs.txt one path per line, relative to musl-1.2.5/ 13 ## crt-mode "asm" or "c" — picked by boot5.sh from $MUSL_DIR 14 ## 15 ## Conventions (cwd-relative; resolves to / under seed init, /work under 16 ## podman bind-mount): 17 ## musl tree in/musl/<rel-path> (read-only; canonical 18 ## tree from prep-src/ 19 ## prep-musl) 20 ## pre-gen hdrs in/musl/obj/include/bits/{alltypes,syscall}.h, 21 ## in/musl/obj/src/internal/version.h 22 ## .o outputs out/obj/musl/<src-with-.o> (rw; pre-mkdir'd by host) 23 ## tcc binary in/tcc (input) 24 ## libtcc1.a in/libtcc1.a (input) 25 ## stdarg bridge in/tcc-stdarg-bridge.h 26 ## hello.c in/hello.c 27 ## exports out/{libc.a,crt1.o,crti.o,crtn.o,hello} 28 ## (flat at out/ root so runscm_export pulls by basename) 29 30 set -eu 31 [ "$#" -eq 3 ] || { echo "usage: $0 <musl-arch> <stage-host-dir> <out.scm>" >&2; exit 2; } 32 33 MUSL_ARCH=$1; STAGE_HOST=$2; OUT=$3 34 SRCS=$STAGE_HOST/build-srcs.txt 35 CRT_MODE=$(cat "$STAGE_HOST/crt-mode") 36 [ -e "$SRCS" ] || { echo "missing $SRCS" >&2; exit 1; } 37 38 CIN=in/musl 39 COUT=out/obj/musl 40 41 # Mirrors boot5.sh's CFLAGS_BASE exactly; the only difference is that 42 # every per-arg token is quoted as its own scheme bytevector. The leading 43 # "in/tcc" is the spawned binary; everything after is its argv. 44 CFLAGS_BASE_QUOTED='"-std=c99" "-nostdinc" "-ffreestanding" "-fno-strict-aliasing" "-D_XOPEN_SOURCE=700"' 45 CFLAGS_BASE_QUOTED="$CFLAGS_BASE_QUOTED \"-I$CIN/arch/$MUSL_ARCH\" \"-I$CIN/arch/generic\" \"-I$CIN/obj/src/internal\" \"-I$CIN/src/include\" \"-I$CIN/src/internal\" \"-I$CIN/obj/include\" \"-I$CIN/include\"" 46 CFLAGS_BASE_QUOTED="$CFLAGS_BASE_QUOTED \"-O2\" \"-fomit-frame-pointer\" \"-Werror=implicit-function-declaration\" \"-Werror=implicit-int\" \"-Werror=pointer-sign\" \"-Werror=pointer-arith\"" 47 CFLAGS_C_QUOTED="$CFLAGS_BASE_QUOTED \"-include\" \"in/tcc-stdarg-bridge.h\"" 48 CFLAGS_ASM_QUOTED="$CFLAGS_BASE_QUOTED" 49 CRTFLAGS_C_QUOTED="$CFLAGS_C_QUOTED \"-fno-stack-protector\" \"-DCRT\"" 50 CRTFLAGS_ASM_QUOTED="$CFLAGS_ASM_QUOTED \"-fno-stack-protector\" \"-DCRT\"" 51 52 # tcc 0.9.26's riscv64-link.c default ELF_START_ADDR=0x10000 sits below 53 # the seed kernel's USER_VA_LO (0x200000); land riscv64 user binaries 54 # in the same 0x600000 window the rest of the chain uses. amd64 55 # (0x400000) and aarch64 (0x400000) defaults already fit the window. 56 case "$MUSL_ARCH" in 57 riscv64) LINK_TTEXT='"-Wl,-Ttext=0x600000"' ;; 58 *) LINK_TTEXT= ;; 59 esac 60 61 { 62 cat <<'PROLOGUE' 63 ;; boot5 run.scm — drive musl-1.2.5 (~500 TUs) + hello. 64 ;; Generated by scripts/boot5-gen-runscm.sh; consumed by both DRIVER=podman 65 ;; (cwd=/work bind mount) and DRIVER=seed (cwd=/, cpio rootfs). The musl 66 ;; source tree is staged read-only at in/tmp/musl-1.2.5/...; per-source .o 67 ;; outputs go to out/obj/musl-1.2.5/...; final artefacts (libc.a, crt1.o, 68 ;; crti.o, crtn.o, hello) land at flat out/ paths so runscm_export can 69 ;; pull them by basename. 70 71 (define (must r tag) 72 (if (and (car r) (= 0 (cdr r))) 73 r 74 (begin 75 (write-string stderr "boot5: step failed: ") 76 (write-string stderr tag) 77 (write-string stderr "\n") 78 (exit 1)))) 79 80 (write-string stdout "boot5: stage A (compile sources)\n") 81 PROLOGUE 82 83 # Stage A: per-source compile. Each line of build-srcs.txt is a path 84 # relative to musl-1.2.5/; choose flags by extension. 85 awk -v CFLAGS_C="$CFLAGS_C_QUOTED" -v CFLAGS_ASM="$CFLAGS_ASM_QUOTED" -v CIN="$CIN" -v COUT="$COUT" ' 86 { 87 src = $0 88 obj = src 89 sub(/\.[^.]*$/, ".o", obj) 90 if (src ~ /\.c$/) flags = CFLAGS_C 91 else if (src ~ /\.[sS]$/) flags = CFLAGS_ASM 92 else flags = CFLAGS_C 93 printf "(must (run \"in/tcc\" %s \"-c\" \"%s/%s\" \"-o\" \"%s/%s\") \"%s\")\n", \ 94 flags, CIN, src, COUT, obj, src 95 }' "$SRCS" 96 97 cat <<EOF 98 99 (write-string stdout "boot5: stage B (CRT)\n") 100 ;; Position-independent + non-PIC CRT helpers. -fPIC objects are needed 101 ;; for shared-binding tools, even though our hello is fully static. 102 (must (run "in/tcc" $CRTFLAGS_C_QUOTED "-fPIC" "-c" "$CIN/crt/Scrt1.c" "-o" "$COUT/crt/Scrt1.o") "Scrt1.o") 103 (must (run "in/tcc" $CRTFLAGS_C_QUOTED "-c" "$CIN/crt/crt1.c" "-o" "$COUT/crt/crt1.o") "crt1.o") 104 (must (run "in/tcc" $CRTFLAGS_C_QUOTED "-fPIC" "-c" "$CIN/crt/rcrt1.c" "-o" "$COUT/crt/rcrt1.o") "rcrt1.o") 105 EOF 106 107 if [ "$CRT_MODE" = asm ]; then 108 cat <<EOF 109 (must (run "in/tcc" $CRTFLAGS_ASM_QUOTED "-c" "$CIN/crt/$MUSL_ARCH/crti.s" "-o" "$COUT/crt/crti.o") "crti.o") 110 (must (run "in/tcc" $CRTFLAGS_ASM_QUOTED "-c" "$CIN/crt/$MUSL_ARCH/crtn.s" "-o" "$COUT/crt/crtn.o") "crtn.o") 111 EOF 112 else 113 cat <<EOF 114 (must (run "in/tcc" $CRTFLAGS_C_QUOTED "-c" "$CIN/crt/crti.c" "-o" "$COUT/crt/crti.o") "crti.o") 115 (must (run "in/tcc" $CRTFLAGS_C_QUOTED "-c" "$CIN/crt/crtn.c" "-o" "$COUT/crt/crtn.o") "crtn.o") 116 EOF 117 fi 118 119 # Stage C: archive libc.a. tcc -ar accepts many obj args; assemble the 120 # full list inline. The list is enormous (~1500 paths × ~40 chars = 121 # ~60 KB on a single line) but the prelude reader handles it fine. 122 { 123 printf '\n(write-string stdout "boot5: stage C (libc.a)\\n")\n' 124 printf '(must (run "in/tcc" "-ar" "rcs" "out/libc.a"' 125 awk -v COUT="$COUT" '{ 126 obj = $0 127 sub(/\.[^.]*$/, ".o", obj) 128 printf " \"%s/%s\"", COUT, obj 129 }' "$SRCS" 130 printf ') "libc.a")\n' 131 } 132 133 cat <<EOF 134 135 ;; Publish CRT objects at flat out/ paths so runscm_export can pull them. 136 (must (run "in/catm" "out/crt1.o" "$COUT/crt/crt1.o") "crt1.o publish") 137 (must (run "in/catm" "out/crti.o" "$COUT/crt/crti.o") "crti.o publish") 138 (must (run "in/catm" "out/crtn.o" "$COUT/crt/crtn.o") "crtn.o publish") 139 140 (write-string stdout "boot5: stage D (link hello)\n") 141 ;; -Lout pulls libc.a (just built); -Lin pulls libtcc1.a (input). 142 (must (run "in/tcc" "-static" "-nostdinc" "-nostdlib" "-include" "in/tcc-stdarg-bridge.h" $LINK_TTEXT 143 "-I$CIN/include" "-I$CIN/arch/$MUSL_ARCH" "-I$CIN/arch/generic" "-I$CIN/obj/include" 144 "out/crt1.o" "in/hello.c" "-Lout" "-lc" "-Lin" "-ltcc1" "-Lout" "-lc" "-o" "out/hello") "link hello") 145 146 (write-string stdout "boot5: ALL-OK\n") 147 (exit 0) 148 EOF 149 } > "$OUT"