boot2

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

boot5-gen-runscm.sh (6905B)


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