RustForge

rust-kernel

Rustbelt: a hobby x86_64 kernel written in Rust

rust-kernel / scripts / run-aarch64.sh
2188 bytes ยท raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#!/usr/bin/env bash
# Stage 22: build the arm64 kernel and boot it on QEMU's "virt" board
# with a Cortex-A53 (the Raspberry Pi 3's CPU).
#
#   scripts/run-aarch64.sh                 # build + boot, output on this terminal
#   scripts/run-aarch64.sh --el2           # start at EL2 (virtualization=on)
#   scripts/run-aarch64.sh --fault         # build with --features aarch64-fault
#   scripts/run-aarch64.sh --no-build ...  # boot what's already built
#   RB_KERNEL=path/to/elf scripts/run-aarch64.sh --no-build   # boot another ELF
#   extra QEMU options go after `--`, e.g.  -- -device virtio-rng-device
#
# The kernel ends the run itself with semihosting SYS_EXIT (that's why
# -semihosting is on), and this script exits with the kernel's status:
# 0 = good, 2 = panic, 3 = exception. A hung kernel is stopped by
# `timeout` after RB_TIMEOUT seconds (default 30) -> status 124.
# Only the QEMU this script started is ever stopped.
set -euo pipefail
cd "$(dirname "$0")/.."
: "${CARGO_TARGET_DIR:=$PWD/target}"
export CARGO_TARGET_DIR
TRIPLE=aarch64-unknown-none-softfloat
MACHINE=virt
FEATURES=aarch64
BUILD=1
EXTRA=()
while [ $# -gt 0 ]; do
    case "$1" in
        --el2) MACHINE=virt,virtualization=on ;;
        --fault) FEATURES=aarch64-fault ;;
        --no-build) BUILD=0 ;;
        --) shift; EXTRA=("$@"); break ;;
        *) echo "unknown option $1" >&2; exit 64 ;;
    esac
    shift
done
if [ "$BUILD" = 1 ]; then
    cargo build --bin rustbelt-aarch64 --features "$FEATURES" --target "$TRIPLE" >&2
fi
KERNEL="${RB_KERNEL:-$CARGO_TARGET_DIR/$TRIPLE/debug/rustbelt-aarch64}"
[ -f "$KERNEL" ] || { echo "no kernel at $KERNEL" >&2; exit 1; }

timeout --foreground "${RB_TIMEOUT:-30}" \
    qemu-system-aarch64 -M "$MACHINE" -cpu cortex-a53 -m 512M \
        -nographic -monitor none -serial stdio -semihosting \
        -kernel "$KERNEL" "${EXTRA[@]}" </dev/null &
TPID=$!
QPID=
for _ in $(seq 40); do
    QPID=$(pgrep -P "$TPID" || true)
    [ -n "$QPID" ] && break
    kill -0 "$TPID" 2>/dev/null || break
    sleep 0.05
done
echo "[run-aarch64] qemu pid ${QPID:-?} (under timeout pid $TPID)" >&2
set +e
wait "$TPID"
rc=$?
echo "[run-aarch64] exit status $rc" >&2
exit $rc