Skip to Content

QEMU Backend

Relevant source files

The QEMU backend serves board virt and is a multi-architecture boot smoke check. All logic lives in runner.py; the shell adapters only select architecture and verb.

Adapters

ScriptBehavior
doctor.shRequires python3, qemu-system-x86_64, qemu-system-aarch64, qemu-system-riscv64
run.shValidates VOLN_VP_ARCH (default aarch64), then exec boards/virt/qemu/<arch>.sh "$@", which runs runner.py <arch> run
test.shexec python3 runner.py "${VOLN_VP_ARCH:-aarch64}" test "$@"

Runner flow

Inputs

ArchRequired
aarch64AXIOMOS_KERNEL, AXIOMOS_DISK_IMAGE
x86_64AXIOMOS_ISO, AXIOMOS_DISK_IMAGE, AXIOMOS_OVMF_CODE, AXIOMOS_OVMF_VARS
riscv64AXIOMOS_KERNEL

Each input must be set and resolve (strictly) to a regular file. Paths containing a comma are rejected because commas delimit QEMU -drive options.

Command

The base command is qemu-system-<arch> -accel tcg -display none -monitor none -serial stdio -no-reboot, followed by the per-architecture flags documented on the virt board page, followed by extra arguments (a leading -- is dropped). The disk image and writable OVMF vars use snapshot=on, so supplied files are never modified. QEMU runs with TMPDIR set to the run directory and no debug or monitor listener.

Markers and failure detection

  • test markers: === axiomos eBPF init === for x86_64/AArch64; axiomos RISC-V demo and Kernel booted via OpenSBI firmware for RISC-V.
  • run uses the same markers unless VOLN_VP_BOOT_MARKER is set; the override never applies to test.
  • Panic detection matches panic/panicked (word boundary, case-insensitive), V04_PANIC, or BOOT_FATAL in a rolling tail buffer, so markers split across reads are still matched.
  • After a panic match the runner waits 0.1 s to capture the reason, then fails with exit 1.
  • After all markers are seen it observes another 0.1 s before declaring PASS and stopping the live guest. This is a boot smoke check, not a soak test.

run vs test

runtest
stdinInherited (interactive)/dev/null
UARTMirrored live to stdout and uart.loguart.log only
MarkerOverridable via VOLN_VP_BOOT_MARKERFixed
TerminalRestored with termios on exitn/a

Exit codes

CodeCause
0Markers observed
1Guest panic/boot fatal, or QEMU exit status 0 before completion
2Bad usage, unsupported arch, missing/invalid input, OSError/ValueError
3qemu-system-<arch> not on PATH
4Invalid VOLN_VP_TIMEOUT
124Timeout (guest or version query)
128+NInterrupted by signal N; QEMU killed by signal N
otherQEMU’s own nonzero exit status

Run directory

voln-vp-qemu-<arch>-XXXXXXXX/ contains:

FileContent
uart.logRaw serial output
qemu.logQEMU stderr
version.logqemu-system-<arch> --version
metadata.jsonarchitecture, verb, inputs (path + sha256 per variable), qemu_version, argv, cwd, timeout_seconds

On failure the runner prints the last 80 lines (from the last 16 KiB) of uart.log, qemu.log, and version.log.

On the unmerged branch stack, AArch64 semihosting becomes opt-in (VOLN_VP_SEMIHOSTING=on, default off), run.sh calls runner.py directly, inputs are copied into the run directory, manifest mode is added, every run writes inputs.json and result.json, and --mode runtime returns unsupported for QEMU. See Contracts.

Last updated on