# qemu ## What is QEMU? **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. ## Install On Debian and Ubuntu: ```bash 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: ```bash sudo dnf install qemu-kvm qemu-user-static ``` To check whether the host supports hardware-accelerated virtualization (needed for KVM mode): ```bash egrep -c '(vmx|svm)' /proc/cpuinfo # nonzero means the CPU supports it kvm-ok # on Ubuntu, reports whether KVM is usable ``` ## Practice Booting a foreign-architecture Linux kernel directly, without a full disk image, is the fastest way to test a freshly cross-compiled kernel: ```bash 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: ```bash 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. ## Concepts ### System mode vs user mode 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." ```bash qemu-system-riscv64 -M virt -kernel Image -nographic # full machine qemu-riscv64 ./binary # single process ``` ### KVM acceleration 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: ```bash 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. ### GDB integration 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: ```bash 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. ### Disk images `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: ```bash qemu-img create -f qcow2 disk.qcow2 20G ```