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 # Disable graphical output, and redirect serial console to qemu processes stdio # (-serial stdio). -nographic

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 use nowait 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

References