Machine Launcher and Debug Profile Matrix
Owner: Developer Tooling Stack roadmap -- Machine Launcher and Debug Profile Matrix section. Audience: developers picking the right launcher for a specific scenario (CPU/SMP, storage, filesystem, secure-boot, bare metal) without script archaeology. Out of scope: release-validation VM flows (owner: Release QA roadmap -- QEMU Validation + VirtualBox Certification) and installer/provisioning VM templates (owner: Unattended Install roadmap -- VM Provisioning Templates). This doc does not duplicate those.
The repository ships one default launcher plus pinned specialist launchers under scripts/machines/. Each launcher below is documented with its host, accelerator, artifacts, debugger entry point, and known limitations.
Default Path
For the common case, prefer the wrappers:
bash scripts/build.sh run-- build + boot in QEMU. Auto-picks KVM on Linux (if/dev/kvmwritable), WHPX on Windows via the.batshims, TCG fallback.bash scripts/run-qemu.sh-- launch without rebuild. Flags:--debug-tests,--test-only,--single-cpu,--debug,--headless,--help.bash scripts/test-smoke.sh-- headless build + boot, 30s timeout, assertsBoot complete in+C:\>on serial. KVM preferred.bash scripts/debug.sh-- launch QEMU with gdb stub on:1234AND start GDB with kernel symbols. Default breakpoints:kernel_main,panic,page_fault_handler,general_protection_fault_handler,double_fault_handler. One-shot launcher; do not use to attach to an already-running VM.
Specialist launchers live under scripts/machines/ (and one under scripts/debug/). Use them when the default path does not match the scenario.
QEMU -- Accelerator and Topology
All QEMU launchers boot build/system-disk.img (GPT: EFI + BlackBox + IXFS) and print to stdout on Linux or a Windows console window.
OVMF_VARS lifecycle. Default run-qemu.sh and Windows run-qemu.ps1 preserve writable EFI variables (build/OVMF_VARS_4M.fd or %TEMP%\OVMF_VARS_4M.fd) across runs -- delete manually, or use reset-qemu-nvram.* on Windows. Forced run-qemu-kvm.sh / run-qemu-tcg.sh recopy build/OVMF_VARS_4M.fd into /tmp/OVMF_VARS_4M_{kvm,tcg}.fd on each launch, but the underlying build/ copy is still stateful; delete it for a pristine run.
Debugger entry point (all QEMU launchers). Linux: bash scripts/debug.sh combines launch + GDB with kernel symbols. Manual attach: add -s -S to the QEMU command line and connect from GDB via target remote localhost:1234. Windows: run-qemu.ps1 accepts -ExtraArgs '-s -S' for the same effect.
Trap behavior caveat. WHPX silently absorbs unknown MSR reads (returns 0, no #GP). KVM and real hardware raise #GP, and the kernel's msr_try_read() probe catches it. If a bug only reproduces on KVM or bare metal, WHPX is hiding it. See CLAUDE.md "Bare Metal Gotchas."
scripts/run-qemu.sh -- Linux / WSL2
- Accelerator: auto (KVM when
/dev/kvmwritable, TCG fallback). - Use: default entry point.
--debugfor gdb stub,--single-cpufor SMP bisect,--headlessfor CI-like.
scripts/machines/run-qemu-kvm.sh -- Linux / WSL2
- Accelerator: KVM (forced;
-enable-kvm -cpu host). - Use: hardware-accelerated CPUID / LAPIC path. Fails fast if
/dev/kvmis missing or unwritable.
scripts/machines/run-qemu-tcg.sh -- Linux / WSL2
- Accelerator: TCG (forced software emulation).
- Use: deterministic, portable; PIT timer path via
platform_is_tcg(). Slow -- not suitable for fast iteration.
scripts/machines/run-qemu-kvm.bat -- Windows
- Accelerator: WHPX (despite the name). Dispatches to
run-qemu.ps1 -Accel whpx. - Use: default Windows interactive launcher.
- Caveat: the name is misleading -- this
.batdoes not use KVM. The bash counterpartrun-qemu-kvm.shdoes.
scripts/machines/run-qemu-tcg.bat -- Windows
- Accelerator: TCG (forced).
- Use: validate the TCG path on Windows without WHPX acceleration.
scripts/machines/run-qemu-1cpu.bat -- Windows
- Accelerator: WHPX, 1 vCPU (
-Smp 1). - Use: SMP bisect. If a crash reproduces with 2 vCPUs but not 1, it is a concurrency bug.
scripts/machines/run-qemu.ps1 -- Windows
- Accelerator:
-Accel auto | whpx | tcg. - Use: underlying PowerShell launcher the
.batshims dispatch to. Direct use for-TestOnly,-TestSuite,-Quiet,-CrashTest,-ErrorScreenTest,-ExtraArgs.
Secure Boot
scripts/debug/kernel/run-secureboot.bat -- Windows
- Accelerator: TCG + q35 + SMM + pflash.
- Use: shim + MokManager + signed EFI Secure Boot validation. First run: enroll
MOK.cervia MokManager. Subsequent runs boot withSecureBoot=1. Requires a pinned shim -- none is pinned today (MS UEFI CA 2011 expired 2026-06-30), so a stock build exercises direct boot, not this flow; restore a chain viascripts/secure-boot/build-shim.shand confirm withscripts/test-secureboot-smoke.sh. - Artifacts:
%TEMP%\OVMF_VARS_secureboot.fd(persists MOK enrollment across runs). Delete to reset. - Debugger:
-s -Saddable via script edit; GDB on SMM paths is tricky -- prefer serial +llvm-addr2line-19. - Caveat: WHPX cannot emulate secboot pflash; this launcher must stay on TCG. Lives under
scripts/debug/due to shim+MOK staging; consolidation underscripts/machines/is a known drift.
VirtualBox
Third-party hypervisor validation (GPU / framebuffer, absolute pointer, VBoxSVGA driver). Artifact: build/system-disk.vdi (re-derived from system-disk.img each run). Requires VirtualBox 7.0+ (AHCI + UEFI). Debugger: no gdb path; use VBoxManage debugvm ImpossibleOS ... for the VBox internal debugger.
scripts/machines/run-vbox.sh -- Linux / WSL2
--headlessfor CI-like.--debugfor debug-boot (X:\DEBUG flag injected).
scripts/machines/run-vbox.ps1 -- Windows
-DebugBootshows live boot output instead of splash.
scripts/machines/run-vbox.bat -- Windows
- Double-click wrapper for
run-vbox.ps1.
Storage Scenarios
-Accel accepts auto | whpx | tcg. Defaults: NVMe and USB scripts default to tcg because WHPX hangs on xHCI and processes NVMe doorbell MMIO writes asynchronously through its event loop.
Debugger. Both storage launchers accept -ExtraArgs '<string>'. Append -s -S to expose the GDB stub; append additional -drive ... / -device ... / -netdev ... fragments to extend the scenario without editing the script. Paths containing spaces survive via double-quoting inside the string (e.g. -ExtraArgs '-drive "id=extra,file=C:\Users\Jane Doe\disk.img,format=raw"'); the launchers use a quote-aware tokenizer rather than a plain space split. The .bat shims forward %* so run-nvme-test.bat -ExtraArgs "-s -S" works from cmd.exe as well.
scripts/machines/storage/run-nvme-test.{ps1,bat} -- Windows
- Params:
-Accel auto|whpx|tcg,-Build,-ExtraArgs '<string>'. - Default accelerator:
tcg. Overridable via-Accel whpx. - Use: 128 MiB emulated NVMe drive alongside the AHCI system disk.
- Caveat: WHPX NVMe admin/I/O timeouts are expected; TCG is the reliable accelerator for NVMe driver runs.
scripts/machines/storage/run-usb-test.{ps1,bat} -- Windows
- Params:
-Accel auto|whpx|tcg,-Build,-ExtraArgs '<string>'. - Default accelerator:
tcg(WHPX hangs with xHCI device attached). - Use: xHCI host-controller scenarios.
- Caveat: xHCI emulation differs from real hardware in port-reset timing; bare metal remains authoritative.
Filesystem Scenarios
run-fs-test.ps1 defaults to -Accel auto. Test output arrives on serial as [PASS] / [FAIL] lines. Debugger: run-fs-test.ps1 accepts -ExtraArgs '-s -S'; the .bat shims (run-fat32-test.bat, run-ntfs-test.bat, run-all-fs-tests.bat) forward %* so the same flag flows through from cmd.exe. run-all-fs-tests.bat applies any forwarded -ExtraArgs to every filesystem in the sweep.
scripts/machines/fs/run-fs-test.ps1 -- Windows
- Params:
-Disk ntfs|fat32|ext2|ext3|ext4|exfat|ixfs|mbr|gpt,-Accel,-Build,-GenDisk,-ExtraArgs '<string>'. - Use: attach a filesystem-specific test disk on AHCI port 1 alongside the system disk. Kernel auto-detects filesystem and runs in-kernel tests when the volume label matches the expected test pattern.
scripts/machines/fs/run-fat32-test.bat -- Windows
- FAT32 driver scenario.
scripts/machines/fs/run-ntfs-test.bat -- Windows
- NTFS driver scenario; auto-generates a 32 MiB test disk via
-GenDisk.
scripts/machines/fs/run-all-fs-tests.bat -- Windows
- Sequential NTFS / FAT32 / ext2 / ext4 / ixfs sweep. Interactive (close QEMU between scenarios).
EFI Variable Reset
scripts/machines/reset-qemu-nvram.{ps1,bat} -- Windows
- Deletes
%TEMP%\OVMF_VARS_4M.fdand%TEMP%\OVMF_VARS_secureboot.fdso the next QEMU launch starts with fresh NVRAM.
Linux equivalent: rm /tmp/OVMF_VARS_4M_{kvm,tcg}.fd between runs (for the forced KVM / TCG launchers) and rm build/OVMF_VARS_4M.fd (for the default run-qemu.sh). No shell script ships today.
Bare-Metal Bring-Up
Bare metal is the shipping target; VM launchers filter regressions but do not replace it.
-
Build the image.
bash scripts/build.sh clean->build/system-disk.img(GPT: EFI + BlackBox + IXFS). Image is self-contained: UEFI bootloader, kernel, user-mode shell, resources, configuration. -
Disk-image handoff. Use the deploy helpers when possible -- they guard against writing to a fixed drive by accident:
- Linux:
sudo bash scripts/deploy/write-usb.sh(lists removable drives only, double-confirm); raw fallbackdd if=build/system-disk.img of=/dev/sdX bs=4M status=progress conv=fsync. - Windows:
scripts/deploy/write-usb.ps1andwrite-usb.bat; raw fallback Win32DiskImager or Rufus. - Target device: USB stick, SATA SSD, or NVMe drive that the target BIOS will boot.
- Linux:
-
Serial capture at 115200 8N1 (matches
src/kernel/drivers/serial.c).- RS-232 header or USB-serial adapter -> host capture:
screen /dev/ttyUSB0 115200,picocom -b 115200 /dev/ttyUSB0, or PuTTY serial mode. - No serial port on the target? Use the on-disk BlackBox partition (step 4) for post-boot diagnostics; framebuffer capture via HDMI/USB capture card is a last resort.
- RS-232 header or USB-serial adapter -> host capture:
-
Post-boot artifact locations (BlackBox FAT32 partition on the system disk, mountable from any OS that speaks FAT32):
X:\Logs\Serial\-- klog output.X:\Boot\-- per-session boot logs.X:\Crash\-- crash recovery + WER-style staging.X:\Perf\,X:\Diag\-- performance and diagnostic dumps.- Full layout and rotation policy:
todo/01-boot-platform/TODO-24-blackbox-service-partition.md.
-
Offline extraction.
bash scripts/tools/read-blackbox.sh-- mount the BlackBox partition frombuild/system-disk.imgor an imaged device.sudo bash scripts/deploy/read-usb-log.sh [/dev/sdX]-- after booting on real hardware, mounts the Logs partition read-only and copiesdebug.log+ hardware info off a USB target.
-
Debugger. No in-kernel gdb stub on bare metal today. Debug via serial log +
llvm-addr2line-19 -e build/kernel.exe -f <RIP>against panic dumps. JTAG / DCI bring-up is future work, not in scope for this doc. -
Bare-metal-only bug classes (VMs hide these): MMIO cache attributes, per-CPU MSRs reset by CR3 reloads, LAPIC TPR writes, SMEP/SMAP state, MTRR/PAT interactions, DMA cache snooping, USB handover timing, firmware variable persistence. See CLAUDE.md "Bare Metal Gotchas." If a regression only manifests on bare metal, invoke
/debug-sessionwith the bare-metal serial capture as evidence.
Known Drift
Surfaced here so new contributors can find them instead of tripping over them:
run-qemu-kvm.batforces WHPX, not KVM. Name is historical and stays to avoid breaking muscle memory.run-qemu-kvm.shdoes use KVM.run-secureboot.batlives underscripts/debug/, notscripts/machines/. Logically a machine profile; consolidation underscripts/machines/is follow-up work.scripts/debug/kernel/run-*-tests.batare not machine profiles -- they are category-specific test runners that wraprun-qemu.ps1 -TestOnly -TestSuite <cat>. Owned by the Wrapper Contract section of the developer tooling roadmap.- Filesystem and storage harnesses are Windows-first. No
.shequivalents today; Linux contributors invokerun-qemu.shwith extra-drive ...manually, or run the Windows-side scripts from WSL2.
Scope Boundary
| Concern | Owner |
|---|---|
| Release-validation VM sweep (QEMU + VirtualBox matrices) | Release QA roadmap -- QEMU + VirtualBox sections |
| Installer / provisioning VM templates | Unattended Install roadmap -- VM Provisioning Templates section |
| Hyper-V certification flows | Release QA roadmap -- Hyper-V Certification section -- deliberately not in the developer matrix |
| Real-hardware certification checklist | Release QA roadmap -- Real Hardware Test Checklist section |
| Performance benchmarks | Release QA roadmap -- Performance Benchmarks section |
| GitHub Actions workflow matrix | Developer Tooling roadmap -- GitHub Actions section |
Updating This Doc
When adding a new launcher:
- Put the script under the correct subdirectory:
scripts/machines/for default-path variants,scripts/machines/fs/orscripts/machines/storage/for scenario-specific variants,scripts/debug/only when the primary purpose is debugging a narrow failure mode. - Add a subsection above with host, accelerator, use, artifacts, debugger entry point, and any known limitations.
- If the new launcher drops an existing entry in Known Drift, delete that entry.
- Cross-check that
docs/infrastructure/development-tooling.mdstill points here and does not inline a parallel launcher list.