summaryrefslogtreecommitdiffstats
path: root/scripts/test-fault.sh
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/test-fault.sh')
-rwxr-xr-xscripts/test-fault.sh53
1 files changed, 15 insertions, 38 deletions
diff --git a/scripts/test-fault.sh b/scripts/test-fault.sh
index 74d83eb..f21596d 100755
--- a/scripts/test-fault.sh
+++ b/scripts/test-fault.sh
@@ -2,26 +2,21 @@
2# 2#
3# scripts/test-fault.sh — fault-diagnostics verification. 3# scripts/test-fault.sh — fault-diagnostics verification.
4# 4#
5# Real hardware has no serial console, so a kernel crash previously left 5# Proves the fault-dump path: every CPU exception prints a white-on-red
6# only a frozen screen ("unresponsive"). This test proves the fault-dump 6# band to the framebuffer and a parseable serial line before halting.
7# path: every CPU exception now prints a white-on-red band to the
8# framebuffer *and* a parseable serial line (vector, error, RIP, CR2,
9# task) before halting — so the next real-hardware failure identifies
10# itself. The `fault` command deliberately writes to an unmapped
11# address; the machine must halt with a full dump, not triple-fault.
12# 7#
13# Usage: ./scripts/test-fault.sh 8# Usage: ./scripts/test-fault.sh
14# Env: OVMF, QEMU (same defaults as other test scripts) 9# Env: OVMF, QEMU, SYSTEM_IMG
15# 10#
16set -euo pipefail 11set -euo pipefail
17 12
18SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" 13SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
19PROJECT_DIR="$(dirname "$SCRIPT_DIR")" 14PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
20cd "$PROJECT_DIR" 15cd "$PROJECT_DIR"
21 16
22OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}" 17OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}"
23QEMU="${QEMU:-qemu-system-x86_64}" 18QEMU="${QEMU:-qemu-system-x86_64}"
24ESP_DIR="$PROJECT_DIR/esp" 19SYSTEM_IMG="${SYSTEM_IMG:-/tmp/system.img}"
25QPID=/tmp/rsdos-fault-qpid 20QPID=/tmp/rsdos-fault-qpid
26SOCK=/tmp/rsdos-fault-qmon.sock 21SOCK=/tmp/rsdos-fault-qmon.sock
27LOG=/tmp/rsdos-fault-serial.log 22LOG=/tmp/rsdos-fault-serial.log
@@ -48,22 +43,20 @@ wait_log() {
48echo "==> 1/5 build kernel (debug)" 43echo "==> 1/5 build kernel (debug)"
49cargo build --package rsdos --target x86_64-unknown-uefi 44cargo build --package rsdos --target x86_64-unknown-uefi
50 45
51echo "==> 2/5 deploy to ESP" 46echo "==> 2/5 stage system image"
52mkdir -p "$ESP_DIR/EFI/BOOT" 47"$SCRIPT_DIR/mksystem.sh" --force "$SYSTEM_IMG"
53cp target/x86_64-unknown-uefi/debug/rsdos.efi "$ESP_DIR/EFI/BOOT/BOOTX64.EFI"
54 48
55echo "==> 3/6 boot QEMU (headless, + dedicated CRASHLOG stick)" 49echo "==> 3/5 boot QEMU (headless, + dedicated CRASHLOG stick)"
56kill "$(cat "$QPID" 2>/dev/null)" 2>/dev/null || true 50kill "$(cat "$QPID" 2>/dev/null)" 2>/dev/null || true
57sleep 1 51sleep 1
58rm -f "$SOCK" "$LOG" 52rm -f "$SOCK" "$LOG"
59# A second FAT32 stick labeled CRASHLOG: crash reports must land here
60# (label-selected by the kernel), not on the boot device.
61CRASH_IMG=/tmp/rsdos-crash.img 53CRASH_IMG=/tmp/rsdos-crash.img
62"$SCRIPT_DIR/mkdisk.sh" --fresh --label CRASHLOG --no-seed "$CRASH_IMG" >/dev/null 54mkfs.fat -C -F 32 -n CRASHLOG "$CRASH_IMG" >/dev/null
63"$QEMU" -bios "$OVMF" \ 55"$QEMU" -bios "$OVMF" \
64 -drive file=fat:rw:"$ESP_DIR",format=raw \ 56 -drive file="$SYSTEM_IMG",format=raw,if=none,id=disk \
57 -device ide-hd,drive=disk,bus=ide.0 \
65 -drive file="$CRASH_IMG",format=raw,if=none,id=crash \ 58 -drive file="$CRASH_IMG",format=raw,if=none,id=crash \
66 -device ide-hd,drive=crash,bus=ide.2 \ 59 -device ide-hd,drive=crash,bus=ide.1 \
67 -serial file:"$LOG" \ 60 -serial file:"$LOG" \
68 -monitor unix:"$SOCK",server,nowait \ 61 -monitor unix:"$SOCK",server,nowait \
69 -m 256M -machine q35 -cpu qemu64 -no-reboot -display none \ 62 -m 256M -machine q35 -cpu qemu64 -no-reboot -display none \
@@ -72,37 +65,21 @@ echo $! >"$QPID"
72 65
73wait_log "$LOG" "boot: entering shell" 90 || fail "kernel never reached the shell" 66wait_log "$LOG" "boot: entering shell" 90 || fail "kernel never reached the shell"
74 67
75echo "==> 4/6 boot diagnostics present" 68echo "==> 4/5 boot diagnostics present"
76grep -aq "gop: fb base=" "$LOG" || fail "fb geometry diagnostic missing" 69grep -aq "gop: fb base=" "$LOG" || fail "fb geometry diagnostic missing"
77grep -aq "gop: mode .* selected" "$LOG" || fail "mode-selection diagnostic missing" 70grep -aq "gop: mode .* selected" "$LOG" || fail "mode-selection diagnostic missing"
78grep -aq "CRASHLOG" "$LOG" || fail "CRASHLOG stick not mounted" 71grep -aq "CRASHLOG" "$LOG" || fail "CRASHLOG stick not mounted"
79 72
80echo "==> 5/6 inject a page fault (fault command)" 73echo "==> 5/5 inject a page fault (fault command)"
81python3 "$SCRIPT_DIR/sendkeys.py" --sock "$SOCK" \ 74python3 "$SCRIPT_DIR/sendkeys.py" --sock "$SOCK" \
82 "clear" \ 75 "clear" \
83 "fault" 76 "fault"
84sleep 2 77sleep 2
85 78
86# The dump must appear on serial: vector 14, the CR2 we wrote, RIP, and
87# the shell task identity — then the machine halts (never triple-faults).
88grep -aq "!!! page fault vec=14 .*rip=" "$LOG" || fail "page-fault dump line missing" 79grep -aq "!!! page fault vec=14 .*rip=" "$LOG" || fail "page-fault dump line missing"
89grep -aq "cr2=0x400000000000" "$LOG" || fail "CR2 not reported (faulting address)" 80grep -aq "cr2=0x400000000000" "$LOG" || fail "CR2 not reported (faulting address)"
90grep -aq "task=0 \"shell\"" "$LOG" || fail "faulting task not identified" 81grep -aq "task=0 \"shell\"" "$LOG" || fail "faulting task not identified"
91grep -aq "!!! halting" "$LOG" || fail "no halt message" 82grep -aq "!!! halting" "$LOG" || fail "no halt message"
92 83
93echo "==> 6/6 crash.log persisted on the CRASHLOG stick"
94grep -aq "crashlog: vol .* (CRASHLOG)" "$LOG" || fail "crashlog did not target the CRASHLOG stick"
95grep -aq "crashlog: wrote" "$LOG" || fail "crashlog write did not complete"
96mdir -i "$CRASH_IMG" "::" 2>/dev/null | grep -aqi "crash" ||
97 fail "crash.log missing on the CRASHLOG stick"
98# The boot ESP must NOT receive the crash log.
99if [ -f "$ESP_DIR/crash.log" ]; then
100 fail "crash.log landed on the boot ESP instead of the CRASHLOG stick"
101fi
102
103# The screen dump itself is exercised in-kernel (dump_lines); the serial
104# path sharing the same format line is verified above.
105echo "" 84echo ""
106echo "PASS — fault dump + crash.log on the CRASHLOG stick" 85echo "PASS — fault dump verified"
107echo " every CPU exception halts with a diagnosable dump; the report"
108echo " survives reboot on the dedicated CRASHLOG volume"