Skip to main content

QEMU Complete Tutorial - Virtualization Guide

Table of Contents

๐Ÿง  What Is QEMU?
#

QEMU (Quick EMUlator) is a generic and open-source emulator and virtualizer.

๐Ÿงฐ QEMU Has Two Main Modes:
#

  1. Emulation Mode:

    • Emulates one hardware architecture on another (e.g., ARM on x86).
    • No hardware acceleration โ€” slower but portable.
  2. Virtualization Mode (with KVM):

    • Runs guest OSes using your CPU’s virtualization features (Intel VT-x, AMD-V).
    • Requires KVM and a Linux host.
    • Much faster, near-native performance.

๐Ÿ–ฅ๏ธ Real-World Use Cases
#

Use CaseDescription
OS DevelopmentTest kernels or bootloaders without rebooting your PC.
Embedded DevelopmentEmulate ARM, RISC-V, MIPS boards on x86.
CI TestingRun headless QEMU in GitHub Actions, Jenkins, etc.
Server VirtualizationLightweight VMs for dev/staging.
Try New OSTest Linux/BSD distros or even Windows without touching your host.

โœ… Installing QEMU in Detail
#

๐Ÿง On Ubuntu/Debian:
#

sudo apt update
sudo apt install qemu qemu-kvm libvirt-daemon-system virtinst bridge-utils virt-manager
  • qemu: Core QEMU binaries
  • qemu-kvm: KVM support for acceleration
  • libvirt-*: Tools for managing VMs
  • virt-manager: GUI tool to manage virtual machines

๐Ÿ” Verify Installation:
#

qemu-system-x86_64 --version

๐Ÿ—๏ธ Step-by-Step VM Creation (x86 Example)
#

๐Ÿ”น Step 1: Create a virtual disk
#

qemu-img create -f qcow2 myvm.qcow2 20G
  • qcow2: QEMU’s optimized disk format (supports snapshots, compression)
  • 20G: Disk size

๐Ÿ”น Step 2: Download an ISO (e.g., Ubuntu, Debian, TinyCore, etc.)
#

Example:

wget https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-*.iso

๐Ÿ”น Step 3: Start VM with ISO
#

qemu-system-x86_64 \
  -hda myvm.qcow2 \
  -cdrom debian.iso \
  -boot d \
  -m 2048 \
  -smp 2 \
  -enable-kvm \
  -cpu host
OptionMeaning
-boot dBoot from CD-ROM
-m 20482GB RAM
-smp 22 CPU cores
-enable-kvmEnables hardware acceleration
-cpu hostUses your host’s CPU features in the VM

๐Ÿ’ก Running QEMU Without GUI (Headless)
#

๐Ÿ“ฆ -nographic
#

qemu-system-x86_64 -hda myvm.qcow2 -m 1024 -nographic
  • Redirects serial output to your terminal.
  • Useful for server OS installs.

Combine with serial monitor:
#

-serial mon:stdio

Example:

qemu-system-x86_64 -hda myvm.qcow2 -m 1024 -nographic -serial mon:stdio

๐ŸŒ Networking Setup
#

๐Ÿงพ Basic NAT Networking
#

-net nic -net user

Adds a virtual NIC and uses user-mode NAT networking.

๐Ÿ”Œ Port Forwarding (e.g., SSH into VM):
#

-net nic -net user,hostfwd=tcp::2222-:22

Then SSH into guest:

ssh -p 2222 user@localhost

๐Ÿ”„ Snapshot Support
#

qemu-system-x86_64 -hda myvm.qcow2 -snapshot
  • All changes are temporary.
  • Use for testing risky software/configs.

๐Ÿ”— Sharing Files Between Host and Guest
#

Using 9p VirtIO (Linux guest):
#

On host:
#

qemu-system-x86_64 \
  -hda myvm.qcow2 \
  -net nic -net user \
  -virtfs local,path=/home/user/shared,security_model=passthrough,mount_tag=hostshare

Inside guest:
#

sudo mount -t 9p -o trans=virtio hostshare /mnt

โš™๏ธ Emulating Other Architectures
#

๐Ÿงฌ ARM Example:
#

qemu-system-arm -M versatilepb -m 256 \
-kernel kernel-qemu -hda raspbian.img \
-append "root=/dev/sda2 rootfstype=ext4 rw" \
-serial stdio -display none
  • -M versatilepb: Emulated ARM board
  • -kernel: Bootloader kernel image
  • -append: Boot parameters

๐Ÿ RISC-V Example:
#

qemu-system-riscv64 \
-machine virt \
-nographic \
-m 1G \
-kernel bbl \
-drive file=rootfs.ext2,format=raw,id=hd0 \
-device virtio-blk-device,drive=hd0

๐Ÿ“Š Disk Image Management
#

Convert a raw disk to qcow2:
#

qemu-img convert -f raw -O qcow2 disk.img disk.qcow2

Resize a disk:
#

qemu-img resize myvm.qcow2 +10G

๐Ÿ”’ Secure and Isolated Testing
#

You can run potentially dangerous software inside a QEMU VM with -snapshot and no network:

qemu-system-x86_64 -hda malware.qcow2 -snapshot -net none

๐Ÿงช Bonus: Run QEMU in Daemon Mode
#

Run VM in the background:

qemu-system-x86_64 -hda myvm.qcow2 -m 1024 -daemonize

Control VM via QEMU monitor socket or SSH.


๐Ÿ›‘ Stop and Kill QEMU VMs
#

List QEMU instances:

ps aux | grep qemu

Kill them:

kill <pid>

๐Ÿ“ QEMU vs VirtualBox vs KVM
#

FeatureQEMUVirtualBoxKVM
GUIโŒ (CLI)โœ…โŒ (with virt-manager)
Headlessโœ…โœ…โœ…
Cross-Arch Emulationโœ…โŒโŒ
SpeedMedium (fast with KVM)GoodVery fast
Snapshot Supportโœ…โœ…โœ…

๐Ÿงญ Summary: What You Can Do with QEMU
#

โœ… Run Linux or BSD headlessly โœ… Emulate ARM/RISC-V boards โœ… Build custom test environments โœ… Automate CI pipelines โœ… Use with Docker for full-stack testing โœ… Perfect for OS/driver/kernel development


Great! Let’s now dive into advanced QEMU usage, focusing on topics like:

  • Custom CPU models
  • BIOS/UEFI boot
  • TPM passthrough
  • Multiple networks/interfaces
  • Advanced QMP (QEMU Machine Protocol) and monitor control
  • Running QEMU as a systemd service
  • Creating templates for reproducible virtual labs
  • Automation with cloud-init and preseed
  • QEMU performance tuning

๐Ÿง  1. Custom CPU Models and Feature Masking
#

Use a specific CPU model:
#

qemu-system-x86_64 -cpu Skylake-Client

Use your host CPU and enable all features:
#

-cpu host,+vmx,+aes,+sse4.2

See available CPU models:
#

qemu-system-x86_64 -cpu help

This is helpful when the guest OS depends on specific features like virtualization, AES instructions, or AVX.


๐Ÿงฐ 2. BIOS vs UEFI Boot
#

BIOS Boot (Default):
#

QEMU uses SeaBIOS by default:

qemu-system-x86_64 -hda disk.qcow2

UEFI Boot:
#

Use OVMF firmware:

๐Ÿ“ฆ Install OVMF (on Ubuntu):
#

sudo apt install ovmf

โœ… Boot with UEFI:
#

qemu-system-x86_64 \
  -drive if=pflash,format=raw,readonly=on,file=/usr/share/OVMF/OVMF_CODE.fd \
  -drive if=pflash,format=raw,file=OVMF_VARS.fd \
  -hda disk.qcow2

๐Ÿ” 3. TPM Passthrough (for Secure Boot / Windows 11)
#

Step 1: Install swtpm
#

sudo apt install swtpm

Step 2: Create a TPM socket and launch QEMU:
#

swtpm socket --tpm2 --ctrl type=unixio,path=/tmp/swtpm-sock &

qemu-system-x86_64 \
  -chardev socket,id=chrtpm,path=/tmp/swtpm-sock \
  -tpmdev emulator,id=tpm0,chardev=chrtpm \
  -device tpm-tis,tpmdev=tpm0 \
  -hda win11.qcow2

This makes Windows 11 or secure-boot Linux guests work.


๐ŸŒ 4. Advanced Networking
#

โœ… Multiple Interfaces:
#

-netdev user,id=net0 -device e1000,netdev=net0 \
-netdev user,id=net1 -device rtl8139,netdev=net1

๐Ÿ›  Tap + Bridge Networking (host integration):
#

  1. Create a tap interface:
sudo ip tuntap add dev tap0 mode tap
sudo ip link set tap0 up
  1. Attach to QEMU:
-netdev tap,id=net0,ifname=tap0,script=no,downscript=no -device virtio-net,netdev=net0

For persistent setup, use bridge-utils or systemd-networkd.


๐Ÿงช 5. Monitor, QMP, and Live Control
#

โŒจ๏ธ Human-readable Monitor:
#

-monitor stdio

๐Ÿง  QMP JSON API:
#

Enable the machine protocol interface:

-qmp unix:/tmp/qmp-sock,server,nowait

Send QMP commands:
#

Use socat:

socat - UNIX-CONNECT:/tmp/qmp-sock

Then send:

{ "execute": "query-status" }

QMP lets you:

  • Hot-plug CPUs, memory, disks
  • Query VM info in JSON
  • Integrate with libvirt, Ansible

๐Ÿงฐ 6. Running QEMU as a Systemd Service
#

Create a service file:

[Unit]
Description=QEMU VM
After=network.target

[Service]
ExecStart=/usr/bin/qemu-system-x86_64 -hda /var/lib/vms/ubuntu.qcow2 -m 2048 -enable-kvm -nographic
Restart=always

[Install]
WantedBy=multi-user.target

Save as /etc/systemd/system/qemu-vm.service, then:

sudo systemctl enable --now qemu-vm

Perfect for headless servers.


๐Ÿ“ฆ 7. Use Cloud-Init for VM Provisioning
#

  1. Download cloud image:
wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img
  1. Create cloud-init ISO:
cloud-localds user-data.img user-data
  1. Boot with cloud-init:
qemu-system-x86_64 \
  -drive file=jammy-server-cloudimg-amd64.img,format=qcow2 \
  -drive file=user-data.img,format=raw \
  -net nic -net user,hostfwd=tcp::2222-:22 \
  -enable-kvm -m 2048

Cloud-init automates:

  • User creation
  • SSH key injection
  • Package install
  • Custom scripts

โšก 8. Performance Tuning
#

Use virtio devices:
#

-device virtio-blk-pci,drive=hd -drive file=vm.qcow2,if=none,id=hd

Use cache=none for best disk performance:
#

-drive file=vm.qcow2,if=virtio,cache=none

Use hugepages:
#

-m 4096 -mem-path /dev/hugepages -mem-prealloc

Enable hugepages on host:

echo 256 > /proc/sys/vm/nr_hugepages

๐Ÿ“ 9. Templates for Lab Automation
#

Create a reusable VM template:
#

  1. Install Linux into a qcow2 image.
  2. Don’t autologin or add user config.
  3. Use cloud-init or kickstart/preseed to auto-configure cloned VMs.
  4. Clone with:
qemu-img create -f qcow2 -b base.qcow2 newlab.qcow2

Linked clones make dev labs fast and space-efficient.


๐Ÿง  10. Other Tips
#

  • Combine with virt-manager or libvirt for hybrid GUI/CLI use.

  • Use SPICE instead of VNC for better graphics:

    -spice port=5930,disable-ticketing
  • Add USB devices:

    -usb -device usb-host,hostbus=1,hostaddr=2
Youcef
Author
Youcef
My name is youcef and i’m linux user who fool in love with linux , like free and open software .