qemu(1)
All the examples & notes use qemu-system-x86_64
but in most cases
this can be swapped with the system emulator for other architectures.
Keybindings
Graphic mode:
Ctrl+Alt+g release mouse capture from VM
Ctrl+Alt+1 switch to display of VM
Ctrl+Alt+2 switch to qemu monitor
No graphic mode:
Ctrl+a h print help
Ctrl+a x exit emulator
Ctrl+a c switch between monitor and console
VM config snippet
Following command-line gives a good starting point to assemble a VM:
qemu-system-x86_64 \
-cpu host -enable-kvm -smp 4 \
-m 8G \
-vga virtio -display sdl,gl=on \
-boot menu=on \
-cdrom <iso> \
-hda <disk> \
-device qemu-xhci,id=xhci \
-device usb-host,bus=xhci.0,vendorid=0x05e1,productid=0x0408,id=capture-card
CPU & RAM
# Emulate host CPU in guest VM, enabling all supported host featured (requires KVM).
# List available CPUs `qemu-system-x86_64 -cpu help`.
-cpu host
# Enable KVM instead software emulation.
-enable-kvm
# Configure number of guest CPUs.
-smp <N>
# Configure size of guest RAM.
-m 8G
Graphic & Display
# Use sdl window as display and enable openGL context.
-display sdl,gl=on
# Use vnc server as display (eg on display `:42` here).
-display vnc=localhost:42
# Confifure virtio as 3D video graphic accelerator (requires virgl in guest).
-vga virtio
Boot Menu
# Enables boot menu to select boot device (enter with `ESC`).
-boot menu=on
Block devices
# Attach cdrom drive with iso to a VM.
-cdrom <iso>
# Attach disk drive to a VM.
-hda <disk>
# Generic way to configure & attach a drive to a VM.
-drive file=<file>,format=qcow2
Create a disk with qemu-img
To create a qcow2
disk (qemu copy-on-write) of size 10G
:
qemu-img create -f qcow2 disk.qcow2 10G
The disk does not contain any partitions
or a partition table
.
We can format the disk from within the guest as following example:
# Create `gpt` partition table.
sudo parted /dev/sda mktable gpt
# Create two equally sized primary partitions.
sudo parted /dev/sda mkpart primary 0% 50%
sudo parted /dev/sda mkpart primary 50% 100%
# Create filesystem on each partition.
sudo mkfs.ext3 /dev/sda1
sudo mkfs.ext4 /dev/sda2
lsblk -f /dev/sda
NAME FSTYPE LABEL UUID FSAVAIL FSUSE% MOUNTPOINT
sda
├─sda1 ext3 ....
└─sda2 ext4 ....
USB
Host Controller
# Add XHCI USB controller to the VM (supports USB 3.0, 2.0, 1.1).
# `id=xhci` creates a usb bus named `xhci`.
-device qemu-xhci,id=xhci
USB Device
# Pass-through USB device from host identified by vendorid & productid and
# attach to usb bus `xhci.0` (defined with controller `id`).
-device usb-host,bus=xhci.0,vendorid=0x05e1,productid=0x0408
Debugging
# Open gdbstub on tcp `<port>` (`-s` shorthand for `-gdb tcp::1234`).
-gdb tcp::<port>
# Freeze guest CPU at startup and wait for debugger connection.
-S
IO redirection
# Create raw tcp server for `serial IO` and wait until a client connects
# before executing the guest.
-serial tcp:localhost:12345,server,wait
# Create telnet server for `serial IO` and wait until a client connects
# before executing the guest.
-serial telnet:localhost:12345,server,wait
# Configure redirection for the QEMU `mointor`, arguments similar to `-serial`
# above.
-monitor ...
In
server
mode usenowait
to execute guest without waiting for a client connection.
Network
# Redirect host tcp port `1234` to guest port `4321`.
-nic user,hostfwd=tcp:localhost:1234-:4321
Shared drives
# Attach a `virtio-9p-pci` device to the VM.
# The guest requires 9p support and can mount the shared drive as:
# mount -t 9p -o trans=virtio someName /mnt
-virtfs local,id=someName,path=<someHostPath>,mount_tag=someName,security_model=none
Debug logging
# List debug items.
-d help
# Write debug log to file instead stderr.
-D <file>
# Examples
-d in_asm Log executed guest instructions.
Tracing
# List name of all trace points.
-trace help
# Enable trace points matching pattern and optionally write trace to file.
-trace <pattern>[,file=<file>]
# Enable trace points for all events listed in the <events> file.
# File must contain one event/pattern per line.
-trace events=<events>
VM snapshots
VM snapshots require that there is at least on qcow2
disk attached to the VM
(VM Snapshots).
Commands for qemu Monitor or QMP:
# List available snapshots.
info snapshots
# Create/Load/Delete snapshot with name <tag>.
savevm <tag>
loadvm <tag>
delvm <tag>
The snapshot can also be directly specified when invoking qemu as:
qemu-system-x86_64 \
-loadvm <tag> \
...
VM Migration
Online
migration example:
# Start machine 1 on host ABC.
qemu-system-x86_64 -monitor stdio -cdrom <iso>
# Prepare machine 2 on host DEF as migration target.
# Listen for any connection on port 12345.
qemu-system-x86_64 -monitor stdio -incoming tcp:0.0.0.0:12345
# Start migration from the machine 1 monitor console.
(qemu) migrate tcp:DEF:12345
Save to external file example:
```bash
# Start machine 1.
qemu-system-x86_64 -monitor stdio -cdrom <iso>
# Save VM state to file.
(qemu) migrate "exec:gzip -c > vm.gz"
# Load VM from file.
qemu-system-x86_64 -monitor stdio -incoming "exec: gzip -d -c vm.gz"
The migration source machine and the migration target machine should be launched with the same parameters.
Appendix: Direct Kernel
boot
Example command line to directly boot a Kernel
with an initrd
ramdisk.
qemu-system-x86_64 \
-cpu host \
-enable-kvm \
-kernel <dir>/arch/x86/boot/bzImage \
-append "earlyprintk=ttyS0 console=ttyS0 nokaslr init=/init debug" \
-initrd <dir>/initramfs.cpio.gz \
...
Instructions to build a minimal Kernel
and initrd
.
Appendix: Cheap instruction tracer
test: test.s
as -o test.o test.s
ld -o test test.o testc.o
trace: test
qemu-x86_64 -singlestep -d nochain,cpu ./test 2>&1 | awk '/RIP/ { print $$1; }'
clean:
$(RM) test test-bin test.o
.section .text, "ax"
.global _start
_start:
xor %rax, %rax
mov $0x8, %rax
1:
cmp $0, %rax
je 2f
dec %rax
jmp 1b
2:
# x86-64 exit(2) syscall
mov $0, %rdi
mov $60, %rax
syscall