A tiny, USB-bootable Linux appliance whose entire job is to boot straight into a QEMU virtual machine β no desktop, no window manager, no host-side UI. You configure a VM once (which disk image, which devices get passed through β keyboard, mouse, sound, camera, USB, network), and every boot from the stick goes: power on β load config β launch that VM with everything passed through β guest shuts down β the physical machine powers off. A direct hardware-to-VM proxy.
Full architecture, configuration reference, and the phased build roadmap live in plan.md. Use RELEASE_CHECKLIST.md before publishing a tagged release.
Active development. The appliance boots into native-qemu-agent, which loads config.toml from the
USB data volume (LABEL=native-qemu) and launches a config-driven QEMU VM (legacy PC profile for
Windows 98 SE first, ReactOS-compatible; qemu-3dfx tuned).
Product track (current CI):
| Piece | What ships today |
|---|---|
| Boot ISO | native-qemu-x86_64.iso β Void Linux glibc live image |
| Host tool | nq-disk for macOS (Apple Silicon), Linux (x86_64 + aarch64), Windows |
| QEMU on the stick | QEMU 9.2.2 + qemu-3dfx installed at /usr/local/bin/qemu-system-x86_64 inside the ISO |
| Extra artifact | qemu-3dfx-x86_64.tar.gz β same prefix tree (devtools / rebuild) |
| Target arch | x86_64 only (no aarch64 appliance ISO) |
Guest data always lives on the USB ext4 volume: config.toml + image.qcow2 (path fixed so you
can swap guests without editing the config).
| Artifact | Runs on |
|---|---|
native-qemu-x86_64.iso |
x86_64 (Intel/AMD) machines (KVM) |
There is no cross-architecture emulation. Flash the stick on any host with nq-disk; boot it
on an x86_64 PC that matches the ISO.
Tagged releases and workflow artifacts are built by .github/workflows/build.yml.
Each platform zip (e.g. native-qemu-macos-arm64.zip, native-qemu-linux-x86_64.zip,
native-qemu-windows-x86_64.zip) contains:
nq-disk/nq-disk.exeβ interactive flash / config / volume toolnative-qemu-x86_64.isoβ boot ISO for the target PCqemu-3dfx-x86_64.tar.gzβ prefix tree withusr/local/bin/qemu-system-x86_64(and tools)README.txtβ short flash instructions
Download from the Releases page or from a green Build ISOs Actions run
(artifact native-qemu-release-packages).
# Host tool
cargo build -p nq-disk --release
# Custom QEMU 9.2 + 3dfx (prefer Void glibc host / container; long build)
./build/qemu-3dfx.sh --pack # β dist/qemu-3dfx-x86_64.tar.gz
# Void glibc ISO with that QEMU + agent baked in (Docker if not on Void)
cargo build -p native-qemu-agent --release
sudo ./build/void-iso.sh \
--qemu-tarball dist/qemu-3dfx-x86_64.tar.gz \
--agent-bin target/release/native-qemu-agent
# β dist/native-qemu-x86_64.isoEvery nq-disk action needs root (raw disks + ext4 data volume). Without elevation it exits
immediately and prints how to re-run.
cd /path/to/unzipped-kit # or next to the .iso
sudo ./nq-disk # macOS / Linux
# Windows: run nq-disk.exe as AdministratorMenu: Flash ISO β pick USB (system disks hidden) β Edit config β Load image β Unmount.
Details: tools/nq-disk/README.md.
Low-level ISO-only write (no data-volume seed):
sudo scripts/write-usb.sh --yes-really-write native-qemu-x86_64.iso /dev/rdiskN # macOS
sudo scripts/write-usb.sh --yes-really-write native-qemu-x86_64.iso /dev/sdX # LinuxCI builds QEMU from download.qemu.org 9.2.2 plus
kjliew/qemu-3dfx on Void glibc, then
build/void-iso.sh installs it into the live root at
/usr/local/bin/qemu-system-x86_64. That is the binary native-qemu-agent runs on the target PC.
# Optional: inspect the same prefix as a tarball
tar tzf qemu-3dfx-x86_64.tar.gz | grep qemu-system-x86_64Guest Glide/OpenGL wrappers (Windows DLLs from qemu-3dfx) are installed inside the guest OS, not by the host flash tool. See the upstream qemu-3dfx README.
Host side, native-qemu-agent prefers /usr/local/bin/qemu-system-x86_64, forces
-display sdl,gl=off (never gl=on β conflicts with 3dfx), and uses a
Windows 98 SEβfirst default profile aligned with the qemu-3dfx wiki:
machine=pc, cpu=host, hpet=off, vga=VGA, AC97, rtl8139, passthrough=both,
-rtc base=localtime. That set also works for ReactOS.
system.timezone = "auto" sets the host zone (detect, else America/Chicago / Texas Central)
so the guest CMOS follows local time. Patched QEMU auto-maps glidept / mesapt on pc;
the agent does not pass -device glidept. Set passthrough = "none" for modern guests
that do not need 3dfx.
- Plug the stick into the x86_64 target machine and open the firmware boot menu.
- Select the USB (BIOS or UEFI).
native-qemu-agentstarts; it uses the data volumeconfig.tomlandimage.qcow2when present.
Preferred: edit on the host with sudo ./nq-disk β Edit config (completion, validate, undo).
On the appliance, the agent resolves config from the data volume / boot media / bundled defaults
(see agent docs and plan.md). Persistence for the stick is the ext4 data volume, not
Alpine lbu (that path is interim-only).
Default profile targets Windows 98 SE + 3dfx (machine=pc, IDE, std VGA, AC97, rtl8139);
ReactOS uses the same devices. Always keep the guest disk filename image.qcow2.
cargo test -p nq-disk
cargo test -p native-qemu-agent --lockedCI jobs (see .github/workflows/build.yml):
QEMU 9.2 + 3dfx (Void glibc)β custom QEMU tarballBuild x86_64 ISO (Void + 3dfx)β boot ISO with QEMU baked innq-disk (*)β host helpersPackage release zipsβ kits above
See repository license files and third-party notices for QEMU / qemu-3dfx / Alpine packaging as applicable.