QEMU - open source processor emulator

mail

qemu-system-x86_64

Flags

Flag Usage
-boot d Specify the boot device :
  • a, b : floppy 1 or 2
  • c : first HDD (default)
  • d : first CD-ROM
  • n-p : Etherboot from network adapter 1-4 (?)
-cdrom file Use file as CD-ROM image. You can use the host CD-ROM by using /dev/cdrom as filename.
-hdc and -cdrom are mutually exclusive.
-cpu cpuModel Select CPU model
  • to list available models : qemu -cpu ?
  • this is not intended as a way to specify 32/64-bit (i386/x86-64) processor. To do so, run either
    • qemu-system-i386
    • qemu-system-x86_64
-curses Normally, QEMU uses SDL to display the VGA output. With this option, QEMU can display the VGA output when in text mode using a curses/ncurses interface. Nothing is displayed in graphical mode.
Using this option without -k fr completely f*cks up my keyboard.
-hda file Use file as hard disk 0 image. And respectively hdb, hdc, hdd for disks 1, 2 and 3 images.
-k language Use keyboard layout language (fr for French). Defaults to en-us.
-m n Set virtual Memory (RAM) size to n MiB. You can specify an optional M or G for MiB or GiB. Defaults to 128 MiB.
-smp n Simulate an SMP system with n CPUs.
Additional parameters are available for sockets, cores and threads : -smp sockets=8,cores=4,threads=4
-snapshot Any changes made to the virtual machine while it is running are written to temporary files and thrown away when the virtual machine is turned off. No changes are saved to the original .img file.
mail

QEMU : setup

QEMU comes in 2 flavors (source) :
mail

QEMU : usage

How to create a new virtual machine ? (see the "impatients" version)

  1. Download an ISO image
  2. Set up a few variables :
    vmName='debian'; diskSize='10G'; ramSize='1G'; qemuWorkDir="$HOME/QEMU/"; mkdir -p "$qemuWorkDir"
  3. Create a new disk image :
    qemu-img create -f qcow2 "$qemuWorkDir/$vmName.img" "$diskSize"
  4. Boot an ISO image to install an operating system :
    When installing Debian :
    • proceed in Expert mode : this is more verbose if something goes wrong
    • at the Installing the base system stage, when offered 2 kernel versions to install :
      • don't pick the linux-image-amd64 version
      • select the linux-image-x.y.z version
  5. Once installed, boot the system :
    qemu-system-x86_64 -enable-kvm -hda "$qemuWorkDir/$vmName.img" -m "$ramSize"

Convert / compress a virtual machine image :

qemu-img convert -c myVirtualMachine.img -O qcow myVirtualMachine.img.compressed

  • qcow is qemu's Copy On Write image format.
  • myVirtualMachine.img.compressed is compressed and still runnable.

Enable networking (source, bridge) :

Looks like this is not necessary anymore as of 2024-08
Run these actions on the host system !
  1. apt install bridge-utils
  2. In /etc/network/interfaces, change the configuration method for the physical interface from auto to manual so that Network Manager (or equivalent) leaves it quiet :
    #auto eth0
    iface eth0 inet manual
  3. Append to /etc/network/interfaces :
    # auto load a bridge
    auto br0
    
    # configure the bridge using DHCP
    iface br0 inet dhcp
    
    	# create a tap device owned by bob (who is a host system user), and turn it up
    	pre-up ip tuntap add dev tap0 mode tap user bob
    	pre-up ip link set tap0 up
    
    	# add all physical interfaces to the bridge
    	bridge_ports all tap0
    
    	# speed up the activating of the bridge (details)
    	bridge_stp		off
    	bridge_maxwait		0
    	bridge_fd		0
    
    	post-down ip link set tap0 down
    	post-down ip tuntap del dev tap0 mode tap
  4. reload changes :
    • service networking restart
    • systemctl restart NetworkManager
  5. Boot the virtual machine with the network management options (details) :
    qemu -hda imagefile.img -net nic -net tap,ifname=tap0,script=no,downscript=no
    The network adapter of the guest system will be configured by the guest system itself with /etc/network/interfaces and DHCP.
  6. To run extra guests simultaneously, create some tap1, tap2, ..., tap devices by duplicating the lines containing tap0 in /etc/network/interfaces.
    • Don't forget to update the ifname=tap... argument of the command above when starting the guest systems.
    • If guests were made by cloning a "master" virtual machine, there are chances the MAC addresses are all the same. Read about how to fix this.

Using snapshots (source)

Create a snapshot :

qemu-img create -f qcow2 -b file.img file.img.snapshot
Thanks to the Copy On Write principle, this is both very fast and highly space efficient but you MUST NOT EVER make any change to file.img - not even boot it - or all snapshots depending on it will be corrupted.

Temporary snapshots

Update the base image

Delete all existing snapshots first, then boot, update (and re-snapshot !).

Commit changes made in a snapshot into the base image :

qemu-img commit file.img.snapshot

The QEMU monitor (source) :

Enter the monitor (on a running machine)
CTRL-ALT-SHIFT-2
Leave the monitor
CTRL-ALT-SHIFT-1
Get info
info cpus

Release mouse grab :

This can be done with CTRL-ALT

Creating a new virtual machine :

  1. Define some shell variables :
    rootDir='/home/bob/'; isoImageFile="${rootDir}path/to/debian-7.3.0-amd64-netinst.iso"; vmDir="${rootDir}Qemu/"; vmFile="${vmDir}debian73x64.img"; vmDiskSizeGb=2; ramMb=1024; nbCpu=2
  2. Create and install the new virtual machine :qemu-img create "$vmFile" "${vmDiskSizeGb}G"; qemu-system-x86_64 -smp $nbCpu -m $ramMb -boot d -hda "$vmFile" -cdrom "$isoImageFile"
  3. Convert and compress the virtual machine image : compressedVmFile="${vmFile}.compressed"; qemu-img convert -c "$vmFile" -O qcow "$compressedVmFile"
  4. Configure networking on the host system
  5. Boot the virtual machine with network support to make sure it's ok :
    qemu-system-x86_64 -smp $nbCpu -m $ramMb -hda "$compressedVmFile" -net nic -net tap,ifname=tap0,script=no,downscript=no
    Once there :
    1. try some pings (to the virtual machine itself, the host system, any external host, ...)
    2. make sure you have all your CPUs : top 1
    3. while in top, check the RAM quantity
  6. If several virtual machines were "snapshoted" from the same initial install :
    1. Assign different MAC addresses manually
    2. Assign static IP addresses manually
  7. When ok, leave top with q and halt the virtual machine.
  8. Start the virtual machine in temporary snapshot mode : qemu-system-x86_64 -smp $nbCpu -m $ramMb -hda "$compressedVmFile" -net nic -net tap,ifname=tap0,script=no,downscript=no -snapshot
  9. Enjoy !