boot4-gen-runscm.sh (6234B)
1 #!/bin/sh 2 ## boot4-gen-runscm.sh — emit run.scm driving boot4's tcc0→tcc1→tcc2→tcc3 3 ## chain inside the seed kernel. Mirrors boot/boot4.sh's per-stage shell 4 ## emission; per-arch values resolved on the host so the .scm body is 5 ## straight-line (run …) calls. 6 ## 7 ## Reads use in/<name>; writes (intermediates and exports) use out/<name>. 8 ## 9 ## Usage: bootprep/boot4-gen-runscm.sh <arch> 10 ## Writes build/<arch>/src/run/boot4.scm. 11 12 set -eu 13 [ "$#" -eq 1 ] || { echo "usage: $0 <arch>" >&2; exit 2; } 14 ARCH=$1 15 OUT=build/$ARCH/src/run/boot4.scm 16 mkdir -p "$(dirname "$OUT")" 17 18 case "$ARCH" in 19 aarch64) LIB_HELPER_SRC=lib-arm64.c; LIB_HELPER_OBJ=lib-arm64.o 20 LIB_HELPER_DEFS='"-D" "HAVE_CONFIG_H=1" "-D" "TCC_TARGET_ARM64=1" "-D" "TCC_TARGET_ARM=1"' 21 LIBTCC1_C_SRCS="lib-arm64.c" 22 LIBTCC1_C_DEFS='"-D" "HAVE_CONFIG_H=1" "-D" "TCC_TARGET_ARM64=1" "-D" "TCC_TARGET_ARM=1"' 23 LIBTCC1_ASM_SRCS="" ;; 24 amd64) LIB_HELPER_SRC=va_list.c; LIB_HELPER_OBJ=va_list.o 25 LIB_HELPER_DEFS='"-D" "TCC_TARGET_X86_64=1"' 26 LIBTCC1_C_SRCS="libtcc1.c va_list.c" 27 LIBTCC1_C_DEFS='"-D" "TCC_TARGET_X86_64=1"' 28 LIBTCC1_ASM_SRCS="alloca86_64.S alloca86_64-bt.S" ;; 29 riscv64) LIB_HELPER_SRC=lib-arm64.c; LIB_HELPER_OBJ=lib-arm64.o 30 LIB_HELPER_DEFS='"-D" "HAVE_CONFIG_H=1" "-D" "TCC_TARGET_RISCV64=1"' 31 LIBTCC1_C_SRCS="lib-arm64.c" 32 LIBTCC1_C_DEFS='"-D" "HAVE_CONFIG_H=1" "-D" "TCC_TARGET_RISCV64=1"' 33 LIBTCC1_ASM_SRCS="" ;; 34 *) echo "boot4-gen: unknown arch $ARCH" >&2; exit 2 ;; 35 esac 36 37 # Per-arch link base for user binaries. tcc 0.9.26's riscv64-link.c 38 # defaults to ELF_START_ADDR=0x10000, which lives below the seed 39 # kernel's USER_VA_LO (0x200000). amd64 (0x400000) and aarch64 40 # (0x400000) defaults already sit inside the user window, so we leave 41 # them alone. Everywhere else in the chain (M0/hex2pp -B, boot6 42 # -Wl,-Ttext) we link riscv64 user binaries at 0x600000; do the same 43 # here so tcc-built outputs are loadable inside the seed kernel. 44 case "$ARCH" in 45 riscv64) LINK_TTEXT='"-Wl,-Ttext=0x600000"' ;; 46 *) LINK_TTEXT= ;; 47 esac 48 49 # emit_helpers — cc reads .S/.c sources from in/, writes .o to out/. 50 # cc_path is the cwd-relative path to the spawned compiler binary (in/tcc0 51 # for round B; out/tcc1, out/tcc2 in later rounds). 52 emit_helpers() { 53 cc_path=$1; tag=$2 54 cat <<EOF 55 (must (run "$cc_path" "-nostdlib" "-c" "-o" "out/start.o" "in/start.S") "$tag start.o") 56 (must (run "$cc_path" "-nostdlib" "-c" "-o" "out/sys_stubs.o" "in/sys_stubs.S") "$tag sys_stubs.o") 57 (must (run "$cc_path" "-nostdlib" "-c" "-o" "out/mem.o" "in/mem.c") "$tag mem.o") 58 (must (run "$cc_path" "-nostdlib" "-c" "-o" "out/libc.o" "in/libc.flat.c") "$tag libc.o") 59 (must (run "$cc_path" "-nostdlib" $LIB_HELPER_DEFS "-c" "-o" "out/$LIB_HELPER_OBJ" "in/$LIB_HELPER_SRC") "$tag $LIB_HELPER_OBJ") 60 EOF 61 } 62 63 # emit_archive — uses prefix to namespace output object names per stage. 64 # pfx="s2-"/"s3-" for stage2/3. The .o objects archived into libtcc1.a 65 # keep their bare basenames (lib-arm64.o, …) — tcc -ar stores basenames 66 # only, so this matches podman's archive members exactly. They overwrite 67 # the stage's helper-named .o files; nothing post-archive in the same 68 # stage reads them as standalone .o. 69 emit_archive() { 70 cc_path=$1; tag=$2; pfx=$3 71 echo "(must (run \"in/catm\" \"out/${pfx}crt1.o\" \"out/start.o\") \"copy crt1.o $pfx\")" 72 echo "(must (run \"$cc_path\" \"-ar\" \"rcs\" \"out/${pfx}libc.a\" \"out/sys_stubs.o\" \"out/mem.o\" \"out/libc.o\") \"$tag ${pfx}libc.a\")" 73 libtcc1_objs="" 74 for src in $LIBTCC1_C_SRCS; do 75 obj=${src%.c}.o 76 echo "(must (run \"$cc_path\" \"-nostdlib\" $LIBTCC1_C_DEFS \"-c\" \"-o\" \"out/${obj}\" \"in/$src\") \"$tag lt ${obj}\")" 77 libtcc1_objs="$libtcc1_objs \"out/${obj}\"" 78 done 79 for src in $LIBTCC1_ASM_SRCS; do 80 obj=${src%.S}.o 81 echo "(must (run \"$cc_path\" \"-nostdlib\" \"-c\" \"-o\" \"out/${obj}\" \"in/$src\") \"$tag lt ${obj}\")" 82 libtcc1_objs="$libtcc1_objs \"out/${obj}\"" 83 done 84 echo "(must (run \"$cc_path\" \"-ar\" \"rcs\" \"out/${pfx}libtcc1.a\"$libtcc1_objs) \"$tag ${pfx}libtcc1.a\")" 85 } 86 87 emit_link_tcc() { 88 cc_path=$1; tag=$2; pfx=$3; out=$4 89 echo "(must (run \"$cc_path\" \"-nostdlib\" $LINK_TTEXT \"out/${pfx}crt1.o\" \"in/tcc.flat.c\" \"out/${pfx}libc.a\" \"out/${pfx}libtcc1.a\" \"out/${pfx}libc.a\" \"-o\" \"out/$out\") \"$tag -> $out\")" 90 } 91 92 { 93 cat <<'PROLOGUE' 94 ;; boot4 run.scm — drive tcc0 -> tcc1 -> tcc2 -> tcc3 inside seed kernel. 95 ;; Generated by bootprep/boot4-gen-runscm.sh; mirrors boot/boot4.sh's 96 ;; podman path stage-for-stage. Reads use in/; writes (intermediates and 97 ;; exports) use out/. tcc0 is staged as in/tcc0; tcc1/tcc2/tcc3 are 98 ;; produced and exported under out/. 99 100 (define (must r tag) 101 (if (and (car r) (= 0 (cdr r))) 102 r 103 (begin 104 (write-string stderr "boot4: step failed: ") 105 (write-string stderr tag) 106 (write-string stderr "\n") 107 (exit 1)))) 108 109 (write-string stdout "boot4: stage B (tcc0 helpers)\n") 110 PROLOGUE 111 112 # Stage B: tcc0 builds helper objects (no archive). 113 emit_helpers in/tcc0 tcc0 114 115 cat <<EOF 116 117 (write-string stdout "boot4: stage C (tcc0 -> tcc1)\n") 118 (must (run "in/tcc0" "-nostdlib" $LINK_TTEXT "out/start.o" "out/sys_stubs.o" "out/mem.o" "out/libc.o" "out/$LIB_HELPER_OBJ" "in/tcc.flat.c" "-o" "out/tcc1") "tcc0 -> tcc1") 119 120 (write-string stdout "boot4: stage D (tcc1 -> tcc2)\n") 121 EOF 122 123 # Stage D: tcc1 rebuilds helpers + archive, links tcc2. 124 emit_helpers out/tcc1 tcc1 125 emit_archive out/tcc1 tcc1 "s2-" 126 emit_link_tcc out/tcc1 tcc1 "s2-" tcc2 127 128 cat <<EOF 129 130 (write-string stdout "boot4: stage E (tcc2 -> tcc3)\n") 131 EOF 132 133 # Stage E: tcc2 rebuilds helpers + archive, links tcc3. 134 emit_helpers out/tcc2 tcc2 135 emit_archive out/tcc2 tcc2 "s3-" 136 emit_link_tcc out/tcc2 tcc2 "s3-" tcc3 137 138 cat <<EOF 139 140 (write-string stdout "boot4: linking hello\n") 141 (must (run "out/tcc2" "-nostdlib" $LINK_TTEXT "out/s3-crt1.o" "in/hello.c" "out/s3-libc.a" "out/s3-libtcc1.a" "out/s3-libc.a" "-o" "out/hello") "tcc2 -> hello") 142 (write-string stdout "boot4: ALL-OK\n") 143 (exit 0) 144 EOF 145 } > "$OUT"