tier1-gate.sh (3316B)
1 #!/bin/sh 2 # tier1-gate.sh — run a single boot2-chain stage binary on the seed 3 # kernel and extract its output files. The chain treats stages as 4 # pure file→file transformations (catm-style), so a Tier 1 acceptance 5 # run is one qemu boot per stage. 6 # 7 # Usage: 8 # tier1-gate.sh <stage-binary> <output-dir> -- <argv...> -- <input-files...> 9 # 10 # Builds an in.img cpio archive containing the stage binary as /init plus 11 # every file from <input-files...> at its basename, runs qemu, and 12 # extracts every file from the post-run SEEDFS image (out.img) into 13 # <output-dir>/. The driver passes <argv...> verbatim through 14 # /chosen/bootargs. 15 # 16 # Example: run boot0 catm to concatenate a + b into out. 17 # tier1-gate.sh build/aarch64/boot0/catm /tmp/out \ 18 # -- init out a b -- /tmp/a /tmp/b 19 20 set -eu 21 22 if [ $# -lt 3 ]; then 23 echo "usage: $0 <stage-binary> <output-dir> -- <argv...> -- <input-files...>" >&2 24 exit 2 25 fi 26 27 STAGE_BIN=$1; shift 28 OUTDIR=$1; shift 29 [ "$1" = "--" ] || { echo "expected -- before argv" >&2; exit 2; } 30 shift 31 32 # Collect argv until next -- 33 ARGV="" 34 while [ $# -gt 0 ] && [ "$1" != "--" ]; do 35 if [ -z "$ARGV" ]; then ARGV=$1; else ARGV="$ARGV $1"; fi 36 shift 37 done 38 [ "${1:-}" = "--" ] || { echo "expected -- before input-files" >&2; exit 2; } 39 shift 40 41 HERE=$(cd "$(dirname "$0")" && pwd) 42 SEED_DIR=$(cd "$HERE/.." && pwd) 43 KERNEL=$SEED_DIR/build/Image 44 EXTRACT=$HERE/extract-blk.sh 45 46 [ -f "$KERNEL" ] || { echo "missing $KERNEL — run 'make' in $SEED_DIR first" >&2; exit 1; } 47 [ -x "$EXTRACT" ] || { echo "missing $EXTRACT" >&2; exit 1; } 48 49 mkdir -p "$OUTDIR" 50 51 # Stage cpio + in.img + out.img. 52 STAGE=$(mktemp -d -t tier1-stage.XXXXXX) 53 trap 'rm -rf "$STAGE"' EXIT 54 55 cp "$STAGE_BIN" "$STAGE/init" 56 chmod +x "$STAGE/init" 57 NAMES="init" 58 for inp in "$@"; do 59 base=$(basename "$inp") 60 cp "$inp" "$STAGE/$base" 61 NAMES="$NAMES 62 $base" 63 done 64 ( cd "$STAGE" && printf '%s\n' "$NAMES" | cpio -o -H newc 2>/dev/null > initramfs.cpio ) 65 # Pad cpio up to a 512-byte multiple so virtio-blk sees whole sectors. 66 sz=$(wc -c < "$STAGE/initramfs.cpio") 67 pad=$(( (512 - sz % 512) % 512 )) 68 if [ "$pad" -gt 0 ]; then 69 head -c "$pad" /dev/zero >> "$STAGE/initramfs.cpio" 70 fi 71 mv "$STAGE/initramfs.cpio" "$STAGE/in.img" 72 truncate -s 256M "$STAGE/out.img" 73 74 # Run qemu, capture transcript, extract. 75 TRANSCRIPT=$STAGE/transcript.txt 76 echo "[gate] running stage with argv: $ARGV" >&2 77 qemu-system-aarch64 \ 78 -machine virt,gic-version=3,accel=hvf -cpu host -m 2048M \ 79 -nographic -no-reboot \ 80 -global virtio-mmio.force-legacy=false \ 81 -kernel "$KERNEL" \ 82 -drive file="$STAGE/in.img",if=none,format=raw,id=hd0,readonly=on \ 83 -device virtio-blk-device,drive=hd0 \ 84 -drive file="$STAGE/out.img",if=none,format=raw,id=hd1 \ 85 -device virtio-blk-device,drive=hd1 \ 86 -append "$ARGV" \ 87 > "$TRANSCRIPT" 2>&1 & 88 QPID=$! 89 # Bound the run; the seed kernel ends with PSCI SYSTEM_OFF on exit, 90 # but on a hang we still need to come back. 91 ( sleep 120; kill -9 $QPID 2>/dev/null ) </dev/null >/dev/null 2>&1 & 92 WATCHER=$! 93 wait $QPID 2>/dev/null || true 94 kill $WATCHER 2>/dev/null || true 95 96 "$EXTRACT" "$OUTDIR" "$STAGE/out.img" >/dev/null 2>&1 || { 97 echo "[gate] FAIL: extract-blk failed (kernel didn't reach exit?)" >&2 98 tail -40 "$TRANSCRIPT" >&2 99 exit 3 100 } 101 echo "[gate] extracted to $OUTDIR" >&2