boot2

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

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"