#!/usr/bin/env bash # ============================================================================ # Rumpk QEMU Runner — Boot, Test, or Interactive Shell # ============================================================================ # Usage: # ./run.sh # Interactive RISC-V session # ./run.sh test # Automated boot test (10s timeout, check output) # ./run.sh [riscv64|aarch64] # Architecture selection (future) # # Exit codes: # 0 = Boot successful (test mode: all checks passed) # 1 = Boot failed or timeout # ============================================================================ set -euo pipefail cd "$(dirname "$0")" MODE="${1:-interactive}" ARCH="${2:-riscv64}" TIMEOUT=25 KERNEL="zig-out/bin/rumpk.elf" DISK="build/disk.img" # Fallback to build/ location if zig-out doesn't have it if [ ! -f "$KERNEL" ]; then KERNEL="build/rumpk-riscv64.elf" fi if [ ! -f "$KERNEL" ]; then echo "ERROR: No kernel binary found. Run: ./build_nim.sh && zig build -Dtarget=riscv64-freestanding-none -Dcpu=sifive_u54" exit 1 fi case "$ARCH" in riscv64) QEMU_CMD=( qemu-system-riscv64 -M virt -m 512M -nographic -kernel "$KERNEL" ) # Add disk if it exists if [ -f "$DISK" ]; then QEMU_CMD+=( -drive "if=none,format=raw,file=$DISK,id=blk0" -device virtio-blk-pci,drive=blk0 ) fi QEMU_CMD+=( -device virtio-net-pci,netdev=net0 -netdev user,id=net0 ) ;; *) echo "ERROR: Architecture '$ARCH' not yet supported" echo "Supported: riscv64" exit 1 ;; esac if [ "$MODE" = "test" ]; then echo "=== Rumpk Boot Test ($ARCH, ${TIMEOUT}s timeout) ===" LOGFILE=$(mktemp /tmp/rumpk-boot-XXXXXX.log) trap "rm -f $LOGFILE" EXIT timeout "$TIMEOUT" "${QEMU_CMD[@]}" > "$LOGFILE" 2>&1 || true # Boot verification checks PASS=0 FAIL=0 TOTAL=0 check() { local name="$1" local pattern="$2" TOTAL=$((TOTAL + 1)) if grep -q "$pattern" "$LOGFILE"; then echo " PASS: $name" PASS=$((PASS + 1)) else echo " FAIL: $name" FAIL=$((FAIL + 1)) fi } check "OpenSBI handoff" "Boot HART ID" check "UART proof-of-life" "UART.*Loopback Test: PASS" check "Zig HAL entry" "zig_entry reached" check "Nim L1 handoff" "Handing off to Nim L1" check "ION pool ready" "ION.*Pool Ready" check "VirtIO-Net init" "VirtIO.*Initialization Complete" check "CSpace init" "Capability system initialized" check "Truth Ledger init" "System Truth Ledger initialized" check "Fiber dispatcher" "Multi-Fiber Dispatcher starting" check "NetSwitch online" "Traffic Engine Online" check "LFS mounted" "Sovereign filesystem mounted" check "Init loaded" "NIPBOX.*Entry point reached" check "Shell spawned" "SOVEREIGN SUPERVISOR" check "DHCP IP acquired" "IP STATUS CHANGE" echo "" echo "=== Result: $PASS/$TOTAL passed, $FAIL failed ===" if [ "$FAIL" -gt 0 ]; then echo "" echo "Boot log saved: $LOGFILE" trap - EXIT # Don't delete on failure exit 1 fi exit 0 elif [ "$MODE" = "interactive" ]; then echo "=== Rumpk Interactive Session ($ARCH) ===" echo " Kernel: $KERNEL" echo " Exit: Ctrl-A X" echo "" exec "${QEMU_CMD[@]}" else echo "Usage: ./run.sh [interactive|test] [riscv64]" exit 1 fi