QEMU is a machine emulator and virtualizer. It can run a full operating system for one CPU architecture on a host of a different architecture by translating instructions on the fly (emulation), or run a guest OS at near-native speed on a matching host architecture by delegating execution to the CPU's own hardware virtualization extensions (KVM acceleration).
These are two different jobs sharing one tool. Pure emulation is what makes QEMU useful for embedded work: you can boot an ARM or RISC-V Linux image on an x86 laptop and get a functioning target environment without owning the physical board, useful for testing a cross-compiled kernel or bootloader before ever touching real hardware. KVM-accelerated virtualization is what makes QEMU useful as a general-purpose VM host, running a same-architecture guest OS at speeds close to bare metal.
In embedded and HPC contexts, QEMU shows up for two distinct reasons: as a target for testing cross-compiled firmware or kernels (qemu-system-arm, qemu-system-riscv64) without hardware in hand, and as qemu-user, which runs a single foreign-architecture binary directly on the host by emulating just that one process rather than a whole machine.
On Debian and Ubuntu:
sudo apt install qemu-system qemu-user-static
qemu-system-* provides full-machine emulation per target architecture; qemu-user-static provides single-binary emulation. On Fedora and RHEL:
sudo dnf install qemu-kvm qemu-user-static
To check whether the host supports hardware-accelerated virtualization (needed for KVM mode):
egrep -c '(vmx|svm)' /proc/cpuinfo # nonzero means the CPU supports it kvm-ok # on Ubuntu, reports whether KVM is usable
Booting a foreign-architecture Linux kernel directly, without a full disk image, is the fastest way to test a freshly cross-compiled kernel:
qemu-system-arm -M versatilepb -kernel zImage \ -dtb versatile-pb.dtb -append "console=ttyAMA0" \ -nographic
-M selects the emulated machine (board) type, which determines the memory map and available peripherals; -nographic redirects the emulated serial console to the host terminal instead of opening a graphical window, the natural mode for headless embedded testing.
qemu-user runs a single cross-compiled binary directly:
qemu-arm ./my_cross_compiled_binary
This works because qemu-user-static registers itself with the kernel's binfmt_misc mechanism, so a foreign-architecture ELF binary can be executed as if it were a native binary; QEMU is invoked transparently underneath.
System-mode QEMU (qemu-system-*) emulates an entire machine, CPU, memory, disk, network interface, peripherals, and boots a full OS image inside it. User-mode QEMU (qemu-arm, qemu-riscv64, etc.) emulates only the CPU instructions of a single process, translating foreign syscalls to the host kernel's native syscalls, which is much lighter weight when the goal is just “run this one binary.”
qemu-system-riscv64 -M virt -kernel Image -nographic # full machine qemu-riscv64 ./binary # single process
When guest and host share the same CPU architecture, QEMU can hand off most instruction execution directly to the CPU via the kernel's KVM module rather than translating instructions in software. This is the difference between a VM running at near-native speed and one running at a fraction of native speed:
qemu-system-x86_64 -enable-kvm -m 4G -smp 4 -hda disk.img
Without -enable-kvm (or on a host without virtualization extensions), QEMU falls back to its software translation engine (TCG), which is what makes cross-architecture emulation possible at all but is considerably slower.
QEMU can expose a GDB remote-debugging stub, which lets gdb attach to and debug code running inside the emulated machine, kernel or bare-metal firmware included, as if it were a normal local process:
qemu-system-arm -M versatilepb -kernel zImage -s -S -nographic
-S freezes the CPU at startup; -s opens a GDB stub on localhost:1234. In another terminal:
gdb zImage (gdb) target remote localhost:1234 (gdb) continue
This combination, QEMU as the target and GDB as the debugger, is the standard way to step through early boot code or a bare-metal firmware image without needing a physical JTAG probe.
qemu-img creates and manipulates the virtual disk images system-mode QEMU boots from, typically in the copy-on-write qcow2 format so a base image can be reused across multiple VMs without duplicating storage:
qemu-img create -f qcow2 disk.qcow2 20G