boot2

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

seed-accept.sh (5935B)


      1 #!/bin/sh
      2 ## seed-accept.sh — Tier-2 acceptance for boot0/1/2 on seed-kernel.
      3 ##
      4 ## Loads the boot2-built scheme1 as /init in the seed kernel, runs a
      5 ## .scm driver that:
      6 ##   1. Logs "hello" to stdout (sys_write fd=1 → UART).
      7 ##   2. Spawns child-prog (=catm from boot2) via clone+execve to
      8 ##      concatenate two files A + B → C in the in-memory tmpfs.
      9 ##   3. waitids the child, reads C back, prints it to stdout.
     10 ##   4. exit_group(0).
     11 ##
     12 ## End-to-end exercise of every Tier-1 syscall (read/write/openat/close/
     13 ## brk/exit_group) plus the three Tier-2 ones (clone/execve/waitid).
     14 ##
     15 ## Verifies the transcript contains the expected log lines and that
     16 ## sys_exit_or_resume_parent saw the child exit cleanly.
     17 ##
     18 ## Usage: scripts/seed-accept.sh
     19 
     20 set -eu
     21 
     22 ARCH=aarch64
     23 ROOT=$(cd "$(dirname "$0")/.." && pwd)
     24 cd "$ROOT"
     25 
     26 KERNEL=build/$ARCH/boot6/Image
     27 EXTRACT=seed-kernel/scripts/extract-blk.sh
     28 SCHEME1=build/$ARCH/boot2/scheme1
     29 CATM=build/$ARCH/boot2/catm
     30 PRELUDE=scheme1/prelude.scm
     31 
     32 [ -f "$KERNEL" ]   || { echo "missing $KERNEL — run ./scripts/boot.sh $ARCH (default DRIVER=podman) first" >&2; exit 1; }
     33 [ -x "$SCHEME1" ]  || { echo "missing $SCHEME1 — run boot2 first" >&2; exit 1; }
     34 [ -x "$CATM" ]     || { echo "missing $CATM — run boot2 first" >&2; exit 1; }
     35 
     36 OUTDIR=$ROOT/build/$ARCH/seed-accept
     37 rm -rf "$OUTDIR"; mkdir -p "$OUTDIR"
     38 
     39 STAGE=$(mktemp -d -t seed-accept.XXXXXX)
     40 trap 'rm -rf "$STAGE"' EXIT
     41 
     42 # ─── driver.scm — the in-VM acceptance program ────────────────────────
     43 cat > "$STAGE/driver.scm" <<'SCM'
     44 ;; driver.scm — Tier-2 acceptance for seed-kernel.
     45 (write-string stdout "scheme1: hello from acceptance driver\n")
     46 (write-string stdout "scheme1: spawning child-prog (catm) C <- A + B\n")
     47 
     48 (let ((r (run "child-prog" "C" "A" "B")))
     49   (if (car r)
     50       (begin
     51         (write-string stdout "scheme1: child returned\n"))
     52       (begin
     53         (write-string stdout "scheme1: spawn FAILED\n")
     54         (exit 1))))
     55 
     56 (let ((rp (open-input "C")))
     57   (if (car rp)
     58       (let* ((p (cdr rp))
     59              (rb (read-all p)))
     60         (if (car rb)
     61             (begin
     62               (write-string stdout "scheme1: read C: [")
     63               (write-bytes stdout (cdr rb))
     64               (write-string stdout "]\n"))
     65             (write-string stdout "scheme1: read C FAILED\n"))
     66         (close p))
     67       (write-string stdout "scheme1: open C FAILED\n")))
     68 
     69 (write-string stdout "scheme1: ALL-OK\n")
     70 (exit 0)
     71 SCM
     72 
     73 # ─── Combine prelude + driver via host catm — this matches the chain's
     74 #     own boot-run-scheme1.sh wrapper, so the .scm shape is identical
     75 #     to what scheme1 expects everywhere. ──────────────────────────────
     76 cat "$PRELUDE" "$STAGE/driver.scm" > "$STAGE/combined.scm"
     77 
     78 # ─── Two demo input files. catm reads them from the in-VM tmpfs. ──────
     79 printf 'Hello, ' > "$STAGE/A"
     80 printf 'seed-kernel!\n' > "$STAGE/B"
     81 
     82 # ─── Stage the cpio: /init=scheme1, /child-prog=catm, plus inputs. ────
     83 mkdir -p "$STAGE/cpio"
     84 cp "$SCHEME1"          "$STAGE/cpio/init";       chmod +x "$STAGE/cpio/init"
     85 cp "$CATM"             "$STAGE/cpio/child-prog"; chmod +x "$STAGE/cpio/child-prog"
     86 cp "$STAGE/combined.scm" "$STAGE/cpio/combined.scm"
     87 cp "$STAGE/A"          "$STAGE/cpio/A"
     88 cp "$STAGE/B"          "$STAGE/cpio/B"
     89 
     90 NAMES='init
     91 child-prog
     92 combined.scm
     93 A
     94 B'
     95 
     96 ( cd "$STAGE/cpio" && printf '%s\n' "$NAMES" | cpio -o -H newc 2>/dev/null ) > "$STAGE/initramfs.cpio"
     97 sz=$(wc -c < "$STAGE/initramfs.cpio")
     98 pad=$(( (512 - sz % 512) % 512 ))
     99 if [ "$pad" -gt 0 ]; then
    100     head -c "$pad" /dev/zero >> "$STAGE/initramfs.cpio"
    101 fi
    102 mv "$STAGE/initramfs.cpio" "$STAGE/in.img"
    103 truncate -s 256M "$STAGE/out.img"
    104 
    105 TRANSCRIPT=$OUTDIR/transcript.txt
    106 echo "[seed-accept] booting scheme1 + driver.scm on seed-kernel"
    107 qemu-system-aarch64 \
    108     -machine virt,gic-version=3,accel=hvf -cpu host -m 2048M \
    109     -nographic -no-reboot \
    110     -global virtio-mmio.force-legacy=false \
    111     -kernel "$KERNEL" \
    112     -drive file="$STAGE/in.img",if=none,format=raw,id=hd0,readonly=on \
    113     -device virtio-blk-device,drive=hd0 \
    114     -drive file="$STAGE/out.img",if=none,format=raw,id=hd1 \
    115     -device virtio-blk-device,drive=hd1 \
    116     -append "init combined.scm" \
    117     > "$TRANSCRIPT" 2>&1 &
    118 QPID=$!
    119 ( sleep 240; kill -9 $QPID 2>/dev/null ) </dev/null >/dev/null 2>&1 &
    120 WATCHER=$!
    121 wait $QPID 2>/dev/null || true
    122 kill $WATCHER 2>/dev/null || true
    123 
    124 # Extract files (we want C from the tmpfs).
    125 if ! "$EXTRACT" "$OUTDIR" "$STAGE/out.img" >/dev/null 2>&1; then
    126     echo "[seed-accept] FAIL: extract-blk failed (kernel didn't reach exit?)" >&2
    127     tail -60 "$TRANSCRIPT" >&2
    128     exit 3
    129 fi
    130 
    131 # ─── Verify ───────────────────────────────────────────────────────────
    132 fail=0
    133 for needle in \
    134     'scheme1: hello from acceptance driver' \
    135     'scheme1: spawning child-prog' \
    136     'scheme1: child returned' \
    137     'scheme1: read C: \[Hello, seed-kernel!' \
    138     'scheme1: ALL-OK' \
    139     'exit_group(0)'
    140 do
    141     if ! grep -q "$needle" "$TRANSCRIPT"; then
    142         echo "[seed-accept] MISSING in transcript: $needle" >&2
    143         fail=1
    144     fi
    145 done
    146 
    147 if [ ! -f "$OUTDIR/C" ]; then
    148     echo "[seed-accept] MISSING extracted file: $OUTDIR/C" >&2
    149     fail=1
    150 elif ! diff -q "$OUTDIR/C" - <<EOF >/dev/null
    151 Hello, seed-kernel!
    152 EOF
    153 then
    154     echo "[seed-accept] C differs from expected:" >&2
    155     od -c "$OUTDIR/C" | head -3 >&2
    156     fail=1
    157 fi
    158 
    159 if [ $fail -ne 0 ]; then
    160     echo "[seed-accept] FAIL — see $TRANSCRIPT" >&2
    161     exit 4
    162 fi
    163 
    164 echo ""
    165 echo "=== driver log (excerpt from transcript) ==="
    166 grep '^scheme1:' "$TRANSCRIPT" || true
    167 echo "==========================================="
    168 echo ""
    169 echo "[seed-accept] PASS — scheme1 + .scm + child-prog cycle complete"
    170 echo "[seed-accept] artifacts in $OUTDIR/"