build-p1.sh (3755B)
1 #!/bin/sh 2 ## build-p1.sh — assemble a P1v2 source (.P1 or .M1) into a runnable ELF. 3 ## 4 ## Pipeline: 5 ## 1. lint — assert every P1v2 op token in <src> is defined 6 ## 2. prune — strip DEFINEs the source doesn't reference 7 ## 3. cat — pruned defs ++ <src> -> combined.M1 8 ## 4. M1 — combined.M1 -> .hex2 9 ## 5. cat — ELF header ++ .hex2 -> linked.hex2 10 ## 6. hex2 — linked.hex2 -> raw ELF 11 ## 7. trim p_filesz, chmod 0700 12 ## 13 ## Modes (selected via M1PP_BOOTSTRAP_TOOLS env): 14 ## default host-side native mescc-tools M1/hex2 (~150x faster 15 ## than stage0 on Apple Silicon). Built on demand by 16 ## scripts/build-native-tools.sh. 17 ## =1 bootstrap M0/hex2-0 inside a busybox container, with 18 ## /tmp staging to dodge per-byte virtiofs syscall storm. 19 ## Output is byte-identical with the native mode. 20 ## 21 ## Usage: scripts/build-p1.sh <arch> <source.P1|.M1> <output_binary> 22 23 set -eu 24 25 if [ "$#" -ne 3 ]; then 26 echo "usage: $0 <arch> <source> <output>" >&2 27 exit 2 28 fi 29 30 ARCH=$1 31 SRC=$2 32 OUT=$3 33 34 REPO=$(cd "$(dirname "$0")/.." && pwd) 35 cd "$REPO" 36 37 case "$ARCH" in 38 aarch64) PLATFORM=linux/arm64 ;; 39 amd64) PLATFORM=linux/amd64 ;; 40 riscv64) PLATFORM=linux/riscv64 ;; 41 *) echo "build-p1.sh: unsupported arch '$ARCH'" >&2; exit 1 ;; 42 esac 43 44 P1_DEFS=build/p1v2/$ARCH/p1_$ARCH.M1 45 ELF_HDR=vendor/seed/$ARCH/ELF.hex2 46 BASE_ADDR=0x600000 ## must match the load address encoded in $ELF_HDR 47 TOOLS=build/$ARCH/tools ## bootstrap M0/hex2-0/catm (when M1PP_BOOTSTRAP_TOOLS=1) 48 49 NAME=$(basename "$SRC" | sed 's/\.[^.]*$//') 50 WORK=build/p1/$ARCH/$NAME.work 51 mkdir -p "$WORK" "$(dirname "$OUT")" 52 53 for f in "$P1_DEFS" "$ELF_HDR" scripts/lint.sh "$SRC"; do 54 if [ ! -e "$f" ]; then 55 echo "build-p1.sh: missing dependency: $f" >&2 56 exit 1 57 fi 58 done 59 60 PRUNED=$WORK/p1.pruned.M1 61 COMBINED=$WORK/combined.M1 62 PROG_HEX2=$WORK/prog.hex2 63 LINKED=$WORK/linked.hex2 64 RAW=$WORK/prog.raw 65 66 sh scripts/lint.sh "$P1_DEFS" "$SRC" 67 68 awk 'NR==FNR{for(i=1;i<=NF;i++)u[$i]=1;next} /^DEFINE /{if($2 in u)print;next} {print}' \ 69 "$SRC" "$P1_DEFS" > "$PRUNED" 70 71 cat "$PRUNED" "$SRC" > "$COMBINED" 72 73 if [ "${M1PP_BOOTSTRAP_TOOLS:-0}" = 1 ]; then 74 for f in "$TOOLS/M0" "$TOOLS/hex2-0" "$TOOLS/catm"; do 75 [ -e "$f" ] || { echo "build-p1.sh: missing bootstrap dependency: $f" >&2; exit 1; } 76 done 77 cat "$ELF_HDR" > "$WORK/elf.hex2" 78 podman run --rm --pull=never --platform "$PLATFORM" \ 79 -v "$REPO":/work -w /work \ 80 "boot2-busybox:$ARCH" sh -ec " 81 set -eu 82 cp $COMBINED /tmp/combined.M1 83 $TOOLS/M0 /tmp/combined.M1 /tmp/prog.hex2 84 cp $WORK/elf.hex2 /tmp/elf.hex2 85 $TOOLS/catm /tmp/linked.hex2 /tmp/elf.hex2 /tmp/prog.hex2 86 $TOOLS/hex2-0 /tmp/linked.hex2 /tmp/prog.raw 87 cp /tmp/prog.hex2 $PROG_HEX2 88 cp /tmp/linked.hex2 $LINKED 89 cp /tmp/prog.raw $RAW 90 " 91 else 92 NATIVE_M1=build/native-tools/M1 93 NATIVE_HEX2=build/native-tools/hex2 94 if [ ! -x "$NATIVE_M1" ] || [ ! -x "$NATIVE_HEX2" ]; then 95 sh scripts/build-native-tools.sh 96 fi 97 "$NATIVE_M1" --architecture "$ARCH" --little-endian \ 98 -f "$COMBINED" -o "$PROG_HEX2" 99 cat "$ELF_HDR" "$PROG_HEX2" > "$LINKED" 100 "$NATIVE_HEX2" --architecture "$ARCH" --little-endian \ 101 --base-address "$BASE_ADDR" \ 102 -f "$LINKED" -o "$RAW" 103 fi 104 105 ## Trim trailing zero padding past p_filesz (lives at byte offset 96 as a 106 ## little-endian u32 in the ELF64 program header). The kernel zero-fills 107 ## the BSS gap up to p_memsz at load time. 108 size=$(od -An -tu4 -N4 -j96 "$RAW" | tr -d ' ') 109 head -c "$size" "$RAW" > "$OUT" 110 chmod 0700 "$OUT"