diff options
| author | salmonik <salmonik@tuta.io> | 2026-08-27 18:35:59 +0200 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-08-27 18:35:59 +0200 |
| commit | acd0fe1bc38746f36fff24a7497041e5c5010977 (patch) | |
| tree | 5db6335b732409c7f180f8514196c52a7b88f434 /scripts/test-fault.sh | |
| parent | GUI: fire-and-forget spawn for /bin/gui binaries (diff) | |
| download | rs-dos-acd0fe1bc38746f36fff24a7497041e5c5010977.tar.gz rs-dos-acd0fe1bc38746f36fff24a7497041e5c5010977.zip | |
scripts: migrate all QEMU/test scripts to single system image
boot.sh: replace esp/ + DISK_IMG with single SYSTEM_IMG on ide.0
(hooks into mksystem.sh --force for auto-staging).
boot-image.sh: delegate to mksystem.sh --chain (build-image.sh deleted).
build-image-release.sh: delegate to mksystem.sh --chain --gpt.
qemu.sh: flexible launcher uses SYSTEM_IMG; --chain flag for
full-chain build.
test-disk.sh: drop ESP_DIR (mksystem.sh stages everything).
test-fault.sh: boot system.img on ide.0 + CRASHLOG stick on ide.1;
replace deleted mkdisk.sh with inline mkfs.fat.
test-gfx.sh: system.img on ide.0, stage via mksystem.sh.
test-mouse.sh: system.img on ide.0, stage via mksystem.sh.
test-msg.sh: system.img on ide.0, stage via mksystem.sh.
Makefile: remove stale build-image.sh/mkdisk.sh references from help;
image target delegates to mksystem.sh --chain.
All scripts syntax-checked (bash -n). build-image.sh and mkdisk.sh
no longer referenced anywhere.
Diffstat (limited to '')
| -rwxr-xr-x | scripts/test-fault.sh | 53 |
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 | # |
| 16 | set -euo pipefail | 11 | set -euo pipefail |
| 17 | 12 | ||
| 18 | SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" | 13 | SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" |
| 19 | PROJECT_DIR="$(dirname "$SCRIPT_DIR")" | 14 | PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" |
| 20 | cd "$PROJECT_DIR" | 15 | cd "$PROJECT_DIR" |
| 21 | 16 | ||
| 22 | OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}" | 17 | OVMF="${OVMF:-/usr/share/edk2/x64/OVMF.4m.fd}" |
| 23 | QEMU="${QEMU:-qemu-system-x86_64}" | 18 | QEMU="${QEMU:-qemu-system-x86_64}" |
| 24 | ESP_DIR="$PROJECT_DIR/esp" | 19 | SYSTEM_IMG="${SYSTEM_IMG:-/tmp/system.img}" |
| 25 | QPID=/tmp/rsdos-fault-qpid | 20 | QPID=/tmp/rsdos-fault-qpid |
| 26 | SOCK=/tmp/rsdos-fault-qmon.sock | 21 | SOCK=/tmp/rsdos-fault-qmon.sock |
| 27 | LOG=/tmp/rsdos-fault-serial.log | 22 | LOG=/tmp/rsdos-fault-serial.log |
| @@ -48,22 +43,20 @@ wait_log() { | |||
| 48 | echo "==> 1/5 build kernel (debug)" | 43 | echo "==> 1/5 build kernel (debug)" |
| 49 | cargo build --package rsdos --target x86_64-unknown-uefi | 44 | cargo build --package rsdos --target x86_64-unknown-uefi |
| 50 | 45 | ||
| 51 | echo "==> 2/5 deploy to ESP" | 46 | echo "==> 2/5 stage system image" |
| 52 | mkdir -p "$ESP_DIR/EFI/BOOT" | 47 | "$SCRIPT_DIR/mksystem.sh" --force "$SYSTEM_IMG" |
| 53 | cp target/x86_64-unknown-uefi/debug/rsdos.efi "$ESP_DIR/EFI/BOOT/BOOTX64.EFI" | ||
| 54 | 48 | ||
| 55 | echo "==> 3/6 boot QEMU (headless, + dedicated CRASHLOG stick)" | 49 | echo "==> 3/5 boot QEMU (headless, + dedicated CRASHLOG stick)" |
| 56 | kill "$(cat "$QPID" 2>/dev/null)" 2>/dev/null || true | 50 | kill "$(cat "$QPID" 2>/dev/null)" 2>/dev/null || true |
| 57 | sleep 1 | 51 | sleep 1 |
| 58 | rm -f "$SOCK" "$LOG" | 52 | rm -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. | ||
| 61 | CRASH_IMG=/tmp/rsdos-crash.img | 53 | CRASH_IMG=/tmp/rsdos-crash.img |
| 62 | "$SCRIPT_DIR/mkdisk.sh" --fresh --label CRASHLOG --no-seed "$CRASH_IMG" >/dev/null | 54 | mkfs.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 | ||
| 73 | wait_log "$LOG" "boot: entering shell" 90 || fail "kernel never reached the shell" | 66 | wait_log "$LOG" "boot: entering shell" 90 || fail "kernel never reached the shell" |
| 74 | 67 | ||
| 75 | echo "==> 4/6 boot diagnostics present" | 68 | echo "==> 4/5 boot diagnostics present" |
| 76 | grep -aq "gop: fb base=" "$LOG" || fail "fb geometry diagnostic missing" | 69 | grep -aq "gop: fb base=" "$LOG" || fail "fb geometry diagnostic missing" |
| 77 | grep -aq "gop: mode .* selected" "$LOG" || fail "mode-selection diagnostic missing" | 70 | grep -aq "gop: mode .* selected" "$LOG" || fail "mode-selection diagnostic missing" |
| 78 | grep -aq "CRASHLOG" "$LOG" || fail "CRASHLOG stick not mounted" | 71 | grep -aq "CRASHLOG" "$LOG" || fail "CRASHLOG stick not mounted" |
| 79 | 72 | ||
| 80 | echo "==> 5/6 inject a page fault (fault command)" | 73 | echo "==> 5/5 inject a page fault (fault command)" |
| 81 | python3 "$SCRIPT_DIR/sendkeys.py" --sock "$SOCK" \ | 74 | python3 "$SCRIPT_DIR/sendkeys.py" --sock "$SOCK" \ |
| 82 | "clear" \ | 75 | "clear" \ |
| 83 | "fault" | 76 | "fault" |
| 84 | sleep 2 | 77 | sleep 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). | ||
| 88 | grep -aq "!!! page fault vec=14 .*rip=" "$LOG" || fail "page-fault dump line missing" | 79 | grep -aq "!!! page fault vec=14 .*rip=" "$LOG" || fail "page-fault dump line missing" |
| 89 | grep -aq "cr2=0x400000000000" "$LOG" || fail "CR2 not reported (faulting address)" | 80 | grep -aq "cr2=0x400000000000" "$LOG" || fail "CR2 not reported (faulting address)" |
| 90 | grep -aq "task=0 \"shell\"" "$LOG" || fail "faulting task not identified" | 81 | grep -aq "task=0 \"shell\"" "$LOG" || fail "faulting task not identified" |
| 91 | grep -aq "!!! halting" "$LOG" || fail "no halt message" | 82 | grep -aq "!!! halting" "$LOG" || fail "no halt message" |
| 92 | 83 | ||
| 93 | echo "==> 6/6 crash.log persisted on the CRASHLOG stick" | ||
| 94 | grep -aq "crashlog: vol .* (CRASHLOG)" "$LOG" || fail "crashlog did not target the CRASHLOG stick" | ||
| 95 | grep -aq "crashlog: wrote" "$LOG" || fail "crashlog write did not complete" | ||
| 96 | mdir -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. | ||
| 99 | if [ -f "$ESP_DIR/crash.log" ]; then | ||
| 100 | fail "crash.log landed on the boot ESP instead of the CRASHLOG stick" | ||
| 101 | fi | ||
| 102 | |||
| 103 | # The screen dump itself is exercised in-kernel (dump_lines); the serial | ||
| 104 | # path sharing the same format line is verified above. | ||
| 105 | echo "" | 84 | echo "" |
| 106 | echo "PASS — fault dump + crash.log on the CRASHLOG stick" | 85 | echo "PASS — fault dump verified" |
| 107 | echo " every CPU exception halts with a diagnosable dump; the report" | ||
| 108 | echo " survives reboot on the dedicated CRASHLOG volume" | ||
