QEMU

From Gentoo Wiki
Jump to:navigation Jump to:search
This page is a translated version of the page QEMU and the translation is 22% complete.
Outdated translations are marked like this.
Other languages:


QEMU(Quick EMUator)是通用开源硬件模拟器和虚拟化套件。

介绍

QEMU是一种硬件模拟器和虚拟化工具,在主机操作系统平台上运行。在虚拟机内部,QEMU可以模拟多个操作系统;它还可以模拟嵌入式系统

QEMU支持32+种CPU。它模拟这些CPU的早期所有操作码。

QEMU有几个插件:Accelerator是其中之一。该插件允许主机CPU的直接执行。使用accelerator时,QEMU执行CPU指令最快

QEMU是一个Type-2 虚拟机管理程序,它在用户命名空间中运行,并执行虚拟硬件模拟。

  • QEMU可以与KVM配对,以near-native speed(几近本机的速度)运行VM。这是通过使用硬件扩展来实现的,如英特尔VT-x或AMD-V。
  • 然后,它可以模拟用户级进程,这些进程允许为一个架构编译的应用程序在另一个架构上运行。
  • 有多种操作模式:用户模式模拟、系统模拟、KVM托管和Xen托管。
  • QEMU可以保存和恢复其所有运行程序的虚拟机状态。
  • QEMU虚拟机可以与许多类型的物理主机硬件交互,例如但不限于CD-ROM驱动器、USB设备、音频接口、硬盘和网卡。
  • 虚拟磁盘映像默认为qcow2格式。这种格式仅使用来宾操作系统增长使用的主机磁盘空间。使用快照方法,来宾操作系统可以及时恢复到其所需的状态。
  • 它不依赖主机系统上的图形输出方法,而是使用集成的VNC服务器访问来宾操作系统的屏幕。
  • 主机CPU上的QEMU可以并行执行多个虚拟CPU。

QEMU支持多个加速器插件:

虚拟化器 加速器 虚拟化类型 说明 Gentoo 包名
qemu tcg full/software emulation QEMU自己的微型代码生成器。这是默认设置。多表示为qemu,而不是qemu/tcg。 emulation/qemu
qemu hvf paravirtualization 基于Intel VT的Apple虚拟机管理程序框架。
qemu whpx[1] hybrid 基于Intel VT或AMD-V的Microsoft Windows虚拟机管理程序平台。
qemu kvm paravirtualization Linux Type-1虚拟机管理程序。这是使用amd64arm64Template:Keyvod [2] 的主机的常见选择。支持Microsoft Windows。 app-emulation/qemu
qemu haxm[3] paravirtualization 英特尔VT,由英特尔公司提供。

QEMU如果与加速器一起使用,将成为在内核命名空间中运行的Type-1虚拟机管理程序。这允许用户命名空间程序访问各种处理器的硬件虚拟化功能。这样的加速器可以是KVM(Kernel-based Virtual Machine)或Xen

如果使用no accelerator,QEMU将完全在用户命名空间中运行,使用其内置二进制转换器TCG(微型代码生成器)。在没有加速器的情况下使用QEMU是"相对低效和缓慢的"。

附注
由于其GPL许可和可用性,本文通常使用KVM作为首选加速器。没有KVM,这里描述的几乎所有命令都将仍然有效(除非特定于KVM)。

以下子条目提供了关于QEMU配置和选项的详细说明:

安装

BIOS 与 UEFI 固件

为了利用KVM,处理器必须支持Vt-x(vmx)或AMD-V(svm)。Vt-x或AMD-V是英特尔和AMD各自的技术,用于允许多个操作系统在处理器上并发执行操作。

要检查硬件的虚拟化支持,请执行以下命令:

user $grep --color --extended-regexp "vmx|svm" "/proc/cpuinfo"
重要
有一段时期,制造商在系统固件中默认关闭虚拟化。在固件中切换此功能可能需要完全断电才能生效。

如果KVM支持可用,则/dev/KVM中应列出KVM设备。这将在系统引导到支持KVM的内核后生效。

内核

下面描述了主机操作系统的KVM内核配置的基本要求。更完整和最新的列表可以在KVM Tuning Kernel页面中找到。

附注
不同的guest(虚拟化)操作系统可能需要额外的内核选项。这些在相应的Usage一节中介绍。
内核 启用"high resolution timer"支持 (CONFIG_HIGH_RES_TIMERS)
General setup --->
 Timers subsystem --->
 <*> High Resolution Timer Support
附注
这包括对ARM64处理器的支持。

物理CPU处理器支持 - 主机

如果KVM支持不可用,请将 CONFIG_KVM=y 插入/usr/src/linux/.config,并重新构建或重新安装内核(及其initramfs映像)。主机重新启动后返回此处。

内核 启用 KVM 支持 (CONFIG_KVM)
[*] Virtualization --->
 <*> Kernel-based Virtual Machine (KVM) support
附注
这包括对ARM64处理器的支持。

处理器支持

内核 启用英特尔处理器的 KVM 支持(CONFIG_KVM_INTEL)
[*] Virtualization --->
 <M> KVM for Intel processors support
内核 启用AMD处理器的 KVM 支持 (CONFIG_KVM_AMD)
[*] Virtualization --->
 <M> KVM for AMD processors support
警告
如果将英特尔处理器的KVM支持AMD处理器的KVM支持 设置为内置在内核中(*),则kprint将在早期启动时返回错误消息。由于系统只能有一种处理器类型:IntelAMD。将一个两个选项启用为"模块"(M)将解决此问题。

在命令行上处理内核配置

要从命令行设置各种内核配置设置,应在此处使用linux/scripts/kconfig/merge_config.sh :

要设置的必需内核配置选项:

文件 /usr/src/kernel-kconfig-qemu-host.config
CONFIG_VIRTUALIZATION=y
CONFIG_KVM=y
CONFIG_KVM_INTEL=y
CONFIG_KVM_AMD=y
root #cd "/usr/src/linux"
root #"./scripts/kconfig/merge_config.sh" ".config" "/usr/src/kernel-kconfig-qemu-host.config"

可用且有用的内核配置选项:

文件 /usr/src/kernel-kconfig-qemu-host-optional.config
CONFIG_VHOST_NET=y
CONFIG_HIGH_RES_TIMER=y
CONFIG_HPET=y
CONFIG_COMPACTION=y
CONFIG_MIGRATION=y
CONFIG_KSM=y
CONFIG_SYSFS=y
CONFIG_PROC_FS=y
CONFIG_TRANSPARENT_HUGEPAGE=y
CONFIG_CGROUPS=y
CONFIG_KVM_HYPERV=y
root #"./scripts/kconfig/merge_config.sh" ".config" "/usr/src/kernel-kconfig-qemu-host-optional.config"
重要
近来,Windows 虚拟机(Windows 10 22H2 或更高版本

要求设置好CONFIG_KVM_HYPERV(如上面的可选配置所言)。如果这被选择,虚拟机将无法配置(或启动),错误如下:Failed to set MSR and Assertion `ret == cpu->kvm_msr_buf->nmsrs' failed.

网络

Accelerated networking, required for vhost-net USE flag (recommend):

内核 vhost-net kernel 5.7 and later (CONFIG_VHOST_NET)
Device Drivers --->
 [*] VHOST drivers --->
 <*> Host kernel accelerator for virtio net
内核 Optional advanced networking support (CONFIG_NET_CORE, CONFIG_TUN)
Device Drivers --->
 [*] Network device support --->
 [*] Network core driver support
 <*> Universal TUN/TAP device driver support

Needed for 802.1d Ethernet bridging:

内核 Enabling 802.1d Ethernet Bridging support (CONFIG_IPV6, CONFIG_BRIDGE)
[*] Networking support --->
 Networking options --->
 <*> The IPv6 protocol
 <*> 802.1d Ethernet Bridging

Intel VT-g (integrated graphics adapter virtualization)

Mediated device passthrough for Intel GPUs (Broadwell to Comet Lake)[4]

内核 Intel VT-g (CONFIG_VFIO_MDEV, CONFIG_DRM_I915_GVT, CONFIG_DRM_I915_GVT_KVMGT)
Device Drivers --->
 <*> VFIO Non-Privileged userspace driver framework
 <*> Mediated device driver framework
 Graphics Support --->
 <*> Intel 8xx/9xx/G3x/G4x/HD Graphics
 [*] Enable Intel GVT-g graphics virtualization host support
 <*> Enable KVM host support Intel GVT-g graphics virtualization

USE flags

Some packages are aware of the qemu USE flag.

Review the possible USE flags for QEMU:

USE flags for app-emulation/qemu QEMU + Kernel-based Virtual Machine userland tools

+aio Enables support for Linux's Async IO
+curl Support ISOs / -cdrom directives via HTTP or HTTPS.
+doc Add extra documentation (API, Javadoc, etc). It is recommended to enable per package instead of globally
+fdt Enables firmware device tree support
+filecaps Use Linux file capabilities to control privilege rather than set*id (this is orthogonal to USE=caps which uses capabilities at runtime e.g. libcap)
+gnutls Enable TLS support for the VNC console server. For 1.4 and newer this also enables WebSocket support. For 2.0 through 2.3 also enables disk quorum support.
+jpeg Enable jpeg image support for the VNC console server
+oss Add support for OSS (Open Sound System)
+pin-upstream-blobs Pin the versions of BIOS firmware to the version included in the upstream release. This is needed to sanely support migration/suspend/resume/snapshotting/etc... of instances. When the blobs are different, random corruption/bugs/crashes/etc... may be observed.
+png Enable png image support for the VNC console server
+seccomp Enable seccomp (secure computing mode) to perform system call filtering at runtime to increase security of programs
+slirp Enable TCP/IP in hypervisor via net-libs/libslirp
+vhost-net Enable accelerated networking using vhost-net, see https://www.linux-kvm.org/page/VhostNet
+vnc Enable VNC (remote desktop viewer) support
X Add support for X11
accessibility Adds support for braille displays using brltty
alsa Enable alsa output for sound emulation
bpf Enable eBPF support for RSS implementation.
bzip2 Enable bzip2 compression support
capstone Enable disassembly support with dev-libs/capstone
debug Enable extra debug codepaths, like asserts and extra output. If you want to get meaningful backtraces see https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Backtraces
fuse Enables FUSE block device export
glusterfs Enables GlusterFS cluster fileystem via sys-cluster/glusterfs
gtk Add support for x11-libs/gtk+ (The GIMP Toolkit)
infiniband Enable Infiniband RDMA transport support
io-uring Enable the use of io_uring for efficient asynchronous IO and system requests
iscsi Enable direct iSCSI support via net-libs/libiscsi instead of indirectly via the Linux block layer that sys-block/open-iscsi does.
jack Add support for the JACK Audio Connection Kit
jemalloc Use dev-libs/jemalloc for memory management
keyutils Support Linux keyrings via sys-apps/keyutils
lzo Enable support for lzo compression
multipath Enable multipath persistent reservation passthrough via sys-fs/multipath-tools.
ncurses Enable the ncurses-based console
nfs Enable NFS support
nls Add Native Language Support (using gettext - GNU locale utilities)
numa Enable NUMA support
opengl Add support for OpenGL (3D graphics)
pam Add support for PAM (Pluggable Authentication Modules) - DANGEROUS to arbitrarily flip
passt Enable TCP/IP in hypervisor via net-misc/passt
pipewire Enable pipewire output for sound emulation
plugins Enable qemu plugin API via shared library loading.
pulseaudio Enable pulseaudio output for sound emulation
python Add optional support/bindings for the Python language
rbd Enable rados block device backend support, see https://docs.ceph.com/en/mimic/rbd/qemu-rbd/
sasl Add support for the Simple Authentication and Security Layer
sdl Enable the SDL-based console
sdl-image SDL Image support for icons
selinux !!internal use only!! Security Enhanced Linux support, this must be set by the selinux profile or breakage will occur
smartcard Enable smartcard support
snappy Enable support for Snappy compression (as implemented in app-arch/snappy)
spice Enable Spice protocol support via app-emulation/spice
ssh Enable SSH based block device support via net-libs/libssh2
static-user Build the User targets as static binaries
systemtap Enable SystemTap/DTrace tracing
test Enable dependencies and/or preparations necessary to run tests (usually controlled by FEATURES=test but can be toggled independently)
udev Enable virtual/udev integration (device discovery, power and storage device support, etc)
usb Enable USB passthrough via dev-libs/libusb
usbredir Use sys-apps/usbredir to redirect USB devices to another machine over TCP
valgrind Enable annotations for accuracy. May slow down runtime slightly. Safe to use even if not currently using dev-debug/valgrind
vde Enable VDE-based networking
virgl Enable experimental Virgil 3d (virtual software GPU)
virtfs Enable VirtFS via virtio-9p-pci / fsdev. See https://wiki.qemu.org/Documentation/9psetup
vte Enable terminal support (x11-libs/vte) in the GTK+ interface
wayland Enable dev-libs/wayland backend
xattr Add support for getting and setting POSIX extended attributes, through sys-apps/attr. Requisite for the virtfs backend.
xdp Enable support for XDP through net-libs/xdp-tools
xen Enables support for Xen backends
zstd Enable support for ZSTD compression
Data provided by the Gentoo Package Database · Last update: 2025年11月04日 09:54 More information about USE flags
附注
More than one USE flag (gtk , ncurses , sdl , or spice ) can be enabled for graphical output. If graphics are desired, it is generally recommended to enable more than one graphical USE flag.
附注
If virt-manager is going to be used, be sure to enable the usbredir and spice USE flags on the qemu package for correct operation.

USE_EXPAND

Additional ebuild configuration are provided as the USE_EXPAND variables QEMU_USER_TARGETS and QEMU_SOFTMMU_TARGETS. See app-emulation/qemu for a list of all the available targets (there are many; most are very obscure and may be ignored; leaving these variables at their default values will disable almost everything, which is probably just fine for most users).

For each target specified, a qemu executable will be built. A softmmu target is the standard qemu use-case of emulating an entire system (like VirtualBox or VMWare, but with optional support for emulating CPU hardware along with peripherals). user targets execute user-mode code only; the (somewhat ambitious) purpose of these targets, is to "magically" allow importing user namespace Linux ELF binaries from a different architecture into the native system (like multilib, without the need for a software stack or CPU capable of running it).

In order to enable QEMU_USER_TARGETS and QEMU_SOFTMMU_TARGETS, use /etc/portage/package.use :

文件 /etc/portage/package.use/qemu
app-emulation/qemu QEMU_SOFTMMU_TARGETS: arm x86_64 sparc QEMU_USER_TARGETS: x86_64

Emerge

After reviewing and adding any desired USE flags, emerge app-emulation/qemu :

root #emerge --ask app-emulation/qemu

Configuration

The following sub-articles provide detailed instructions on QEMU configurations and options:

Environment variables

name description
G_MESSAGES_DEBUG Enables debug messages for components using GLib's logging system. If set to all, it outputs to stderr. Other options are all, QEMU, libvirt, gtk, and pulse. Use comma to separate multiple option.
LISTEN_FDS Number of file descriptors passed. Used with QEMU activated by systemd.
LISTEN_PID PID of the receiving process (usually set to the current PID). Used with QEMU activated by systemd.
QEMU_AUDIO_DRV Specifies the audio backend driver to use (options are alsa, pa, oss, none).
XDG_RUNTIME_DIR Specifies where user-specific runtime files and sockets should be stored (e.g., /run/user/UID/). Commonly used by Wayland, PulseAudio, or virt-manager.

Files

Files that QEMU uses.

Single File

  • /etc/libvirt/qemu.conf - QEMU configuration file.
  • /etc/libvirt/qemu-lockd.conf - QEMU lock files
  • /etc/libvirt/qemu-sanlock.conf - QEMU SAN lock
  • /etc/libvirt/qemu/<domain-name>.xml - Domain XML setting for a virtual machine or container.
  • /etc/libvirt/qemu/autostart/<domain-name>.xml - Autostart this domain (virtual machine or container).
  • /etc/libvirt/qemu/networks/<network-name>.xml - Network XML setting file for a network connection
  • /etc/libvirt/qemu/networks/autostart/<network-name>.xml - Autostart this network connection.
  • /var/lib/libvirt/qemu/channel/target/<domain-name>/<socket-file> - UNIX socket file for Libvertd daemon API
  • /var/cache/libvirt/qemu/capabilities/<hash-value>.xml - Host OS capabilities in XML format
  • /var/lib/libvirt/qemu/checkpoint/
  • /var/lib/libvirt/qemu/<domain-9-XXXX>/ - holds UNIX sockets and AES keys for this domain.
  • /var/lib/libvirt/qemu/dump/
  • /var/lib/libvirt/qemu/nvram/
  • /var/lib/libvirt/qemu/ram/
  • /var/lib/libvirt/qemu/save/ - holding directory of hibernation images
  • /var/lib/libvirt/qemu/snapshot/ - holding directory of snapshots
  • /var/run/libvirt/qemu - various UNIX socket and PID files for the libvirtd daemon.

Image File

QEMU supports the following disk image formats:

  • QEMU copy-on-write (.qcow2, .qed, .qcow, .cow)
  • VirtualBox Virtual Disk Image (.vdi)
  • CD/DVD (ISO-9660) images (.iso)
  • Raw images (.img), that guest OS can control
  • VFAT-16
  • VMware Virtual Machine Disk (.vmdk)
  • Virtual PC Virtual Hard Disk (.vhd)
  • Parallels disk image (.hdd, .hds) – Read-only
  • Apple macos Universal Disk Image Format (.dmg) – Read-only
  • Bochs – Read-only
  • Linux cloop – Read-only

Additional software

To connect to the SPICE server of QEMU, a GUI client like net-misc/spice-gtk is required.

Usage

QEMU can be used with GUI front-ends or via the command line. There are multiple user-friendly front ends to QEMU: See Front-ends.

Invocation

QEMU supports around 34 different CPU architectures. To find the desired architecture, one can list them like so:

user $ls "/usr/bin/qemu-system-"*
/usr/bin/qemu-system-aarch64 /usr/bin/qemu-system-mips /usr/bin/qemu-system-rx
/usr/bin/qemu-system-alpha /usr/bin/qemu-system-mips64 /usr/bin/qemu-system-s390x
/usr/bin/qemu-system-arm /usr/bin/qemu-system-mips64el /usr/bin/qemu-system-sh4
/usr/bin/qemu-system-avr /usr/bin/qemu-system-mipsel /usr/bin/qemu-system-sh4eb
/usr/bin/qemu-system-cris /usr/bin/qemu-system-nios2 /usr/bin/qemu-system-sparc
/usr/bin/qemu-system-hppa /usr/bin/qemu-system-or1k /usr/bin/qemu-system-sparc64
/usr/bin/qemu-system-i386 /usr/bin/qemu-system-ppc /usr/bin/qemu-system-tricore
/usr/bin/qemu-system-loongarch64 /usr/bin/qemu-system-ppc64 /usr/bin/qemu-system-x86_64
/usr/bin/qemu-system-m68k /usr/bin/qemu-system-ppc64le /usr/bin/qemu-system-x86_64-microvm
/usr/bin/qemu-system-microblaze /usr/bin/qemu-system-riscv32 /usr/bin/qemu-system-xtensa
/usr/bin/qemu-system-microblazeel /usr/bin/qemu-system-riscv64 /usr/bin/qemu-system-xtensaeb

Permissions

In order to run a KVM-accelerated virtual machine without root privileges, one can add normal users to the kvm group:

root #gpasswd -a larry kvm

Creation of a disk image

To create a raw disk image with 4 GiB size:

user $qemu-img create -f raw "/home/larry/qemu/my-systems-disk-image.img" 4G
Formatting 'my-systems-disk-image.img', fmt=raw size=4294967296
user $ls -lh
total 4
-rw-r--r-- 1 larry larry 4.0G Apr 12 11:23 my-systems-disk-image.img

To create a raw disk image with copy-on-write disabled:

user $qemu-img create -f raw "/home/larry/qemu/my-systems-disk-image.img" -o nocow=on 4G
Formatting 'my-systems-disk-image.img', fmt=raw size=4294967296 nocow=on
user $ls -lh
total 4
-rw-r--r-- 1 larry larry 4.0G Apr 12 11:23 my-systems-disk-image.img

The option nocow is also a file attribute, which can be determined via the command lsattr[5] .

The following will create a qcow2 disk image (useful, if the host filesystem does not support sparse files):

user $qemu-img create -f qcow2 "/home/larry/qemu/my-systems-disk-image.qcow2" 4G
Formatting 'my-systems-disk-image.qcow2', fmt=qcow2 cluster_size=65536 extended_l2=off compression_type=zlib size=4294967296 lazy_refcounts=off refcount_bits=16
user $ls -l
total 196K
-rw-r--r-- 1 larry larry 193K Apr 12 11:30 my-systems-disk-image.qcow2

Preparation of a bootable disk image from scratch

A system can be copied onto a disk image, when not using a CD-ROM installation medium.

By default, qemu uses a bios-firmware to boot the system.

The disk can be prepared with a msdos disk label and a gap between the end of the 512-byte-MBR (Master Boot Record) and the start of the first partition. The gap is needed for boot loaders like GRUB, which place boot-code within this gap.

The following example uses the raw disk image, which was created above.

A raw disk image can be prepared by attaching it as a loop device:

root #losetup --find --partscan --show "/home/larry/qemu/my-systems-disk-image.img"
/dev/loop0
  • The parameter --find finds the first unused loop device.
  • The parameter --partscan forces the Linux kernel to scan the partition table on the newly created loop device, where the default sector size of 512 bytes is assumed.
  • The parameter --show displays the name of the assigned loop device, if the parameter --find is used.

Attached loop devices can be listed with the following command:

root #losetup --list
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC
/dev/loop0 0 0 0 0 /home/larry/qemu/my-systems-disk-image.img 0 512

Then, the loop device can be formatted like a normal disk.

Print the partition table:

root #parted "/dev/loop0" "unit mib print"
Error: /dev/loop0: unrecognised disk label
Model: Loopback device (loopback)
Disk /dev/loop0: 4096MiB
Sector size (logical/physical): 512B/512B
Partition Table: unknown
Disk Flags:

Create a new partition table (msdos disk label):

警告
Make absolutely sure to select the correct loop device, since this may overwrite an existing partition table; resulting in data loss, if the overwritten partition table cannot be recovered.
root #parted "/dev/loop0" "mklabel msdos"
Information: You may need to update /etc/fstab.

The returned information can be ignored, since an entry in the configuration file /etc/fstab is not needed.

parted now indicates, that the partition table}} is msdos:

root #parted "/dev/loop0" "unit mib print"
Model: Loopback device (loopback)
Disk /dev/loop0: 4096MiB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
 
Number Start End Size Type File system Flags

Create an ext4 partition with an offset of 2 MiB:

root #parted "/dev/loop0" "mkpart primary ext4 2MiB -1"

The parameter -1 represents the last sector of the partition.

The first partition has been successfully created:

root #parted "/dev/loop0" "unit mib print"
Model: Loopback device (loopback)
Disk /dev/loop0: 4096MiB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
 
Number Start End Size Type File system Flags
 1 2.00MiB 4095MiB 4093MiB primary

This will also attach a new loop device at /dev/loop0p1:

root #ls -l "/dev/loop0"*
brw-rw---- 1 root disk 7, 0 Apr 12 12:33 /dev/loop0
brw-rw---- 1 root disk 259, 0 Apr 12 12:33 /dev/loop0p1

Set the boot flag:

root #parted "/dev/loop0" set 1 boot on

All partition flags can be found in the column "Flags":

root #parted "/dev/loop0" "unit mib print"
Model: Loopback device (loopback)
Disk /dev/loop0: 4096MiB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
 
Number Start End Size Type File system Flags
 1 2.00MiB 4095MiB 4093MiB primary boot

Create the ext4 filesystem, which was declared via parted earlier:

root #mkfs.ext4 "/dev/loop0p1"
mke2fs 1.47.2 (1-Jan-2025)
Discarding device blocks: done
Creating filesystem with 1047808 4k blocks and 262144 inodes
Filesystem UUID: 0e344af7-6f7b-4d27-8238-89d46a5920d6
Superblock backups stored on blocks:
 32768, 98304, 163840, 229376, 294912, 819200, 884736
 
Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done

Mount it at /mnt:

root #mount /dev/loop0p1 /mnt
root #df --human-readable --print-type "/mnt/"
Filesystem Type Size Used Avail Use% Mounted on
/dev/loop0p1 ext4 3.9G 24K 3.7G 1% /mnt

Create the directories /mnt/boot/grub, which will be used by GRUB later:

root #mkdir --parents --verbose "/mnt/boot/grub"
mkdir: created directory '/mnt/boot'
mkdir: created directory '/mnt/boot/grub'

Install GRUB boot loader on the loop device and advice it to install its files to /mnt/boot/grub/:

root #grub-install --target="i386-pc" --boot-directory="/mnt/boot/" "/dev/loop0"
root #tree -F "/mnt/boot/grub/"
/mnt/boot/grub/
├── fonts/
│   └── unicode.pf2
├── grubenv
├── i386-pc/
│   ├── acpi.mod
│   ├── adler32.mod
│   ├── affs.mod
│   ├── afs.mod
│   ├── afsplitter.mod
│   ├── ahci.mod
│   ├── all_video.mod
│   ├── aout.mod
│   ├── archelp.mod
│   ├── ata.mod
[...]

Unmount the filesystem and detach the loop device:

root #umount "/mnt/"
root #losetup --detach "/dev/loop0"

If the loop device is still busy - for example, processes are still accessing /mnt/ - no error will be returned. This can be verified and solved with the following commands:

root #losetup --list
NAME SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE DIO LOG-SEC
/dev/loop0 0 0 0 0 /home/larry/qemu/my-systems-disk-image.img 0 512
root #lsof | grep "/mnt"
sleep 31813 root cwd DIR 259,0 4096 131074 /mnt/boot/grub
root #kill -SIGTERM 31813

This is sufficient to boot into a grub2 boot prompt. This is can be used as the basis for a bootable system.

CPU selection

QEMU CPU selections have additional support for accelerators, like kvm (Kernel Virtual Machine), tcg (Tiny Code Generator) or Xen.

The accelerator can usually only accelerate the features, which are available on the host CPU. So the selection of the CPU affects the performance.

To get a list of CPUs, one can use the parameters -cpu help.

To show available accelerators, one can use the parameters -accel help.

Starting QEMU

The following explains, how to start a virtual machine with the same feature set as the host CPU, a raw disk image and 2 GB of RAM.

By default, a VNC server starts without password protection and listens on the loop interface. QEMU is advised to listen on a local UNIX socket with the following command:

user $qemu-system-x86_64 -vnc "unix:/run/user/$(id --user)/qemu-vnc.sock" -enable-kvm -cpu host -drive "file=/home/larry/qemu/my-systems-disk-image.img,format=raw" -m 2G
警告
Set the file permissions of /run/user/$(id --user)/qemu-vnc.sock appropriately, in order to protect the VNC server from unauthorized access! If the virtual machine is started with the parameter -vnc :0, it will listen on port 5900 on all interfaces without password protection! The parameter :0 represents the first display of the host machine, which may be mistaken as a port number!
附注
A CD-ROM installation or boot medium can be added via the parameter -cdrom. For example: -cdrom filename.iso

Connecting to the virtual machine via VNC

In order to connect to the VNC server, the command vncviewer, which comes from the package net-misc/tigervnc , can be used:

user $vncviewer "/run/user/$(id --user)/qemu-vnc.sock"
TigerVNC viewer v1.15.0
Built on: 2025年05月13日 12:30
Copyright (C) 1999-2025 TigerVNC team and many others (see README.rst)
See https://www.tigervnc.org for information on TigerVNC.
 
Tue May 13 14:44:36 2025
 DecodeManager: Detected 4 CPU core(s)
 DecodeManager: Creating 4 decoder thread(s)
 CConn: Connected to socket /run/user/1000/qemu-vnc.sock
 CConnection: Server supports RFB protocol version 3.8
 CConnection: Using RFB protocol version 3.8
 CConnection: Choosing security type None(1)
 CConn: Using pixel format depth 24 (32bpp) little-endian rgb888
 CConn: SetDesktopSize failed: 3

This will open a separate window, where one gets greeted with a GRUB shell, which was installed via grub-install earlier:

Troubleshooting

qemu-system-x86_64: CPU model 'host' requires KVM or HVF

When trying to start a virtual machine, using the parameter -cpu host, one may encounter the following error:

代码 CPU model 'host' requires KVM or HVF
qemu-system-x86_64: CPU model 'host' requires KVM or HVF

In order to fix this, use the parameter -enable-kvm, which will enable KVM full virtualization support:

user $qemu-system-x86_64 -cpu host -enable-kvm [...]

kvm: already loaded the other module

Sometimes, during the early boot splash, the following error message may be seen:

代码 kvm: already loaded the other module
kvm: already loaded the other module.

This indicates, that both, the Intel and the AMD kernel virtual machine settings, have been enabled in the kernel. To fix this, enable it as a module or disable either the Intel or AMD KVM option specific to the system's processor in the kernel configuration as described above.

Creating TUN/TAP device - No such file or directory

Sometimes, this error can occur, if TUN/TAP support cannot be found in the kernel. To solve this, try loading the tun kernel module:

root #modprobe tun

If this works, add tun to a file in /etc/modules-load.d/, so the kernel module will be loaded on every boot of the host system:

文件 /etc/modules-load.d/qemu-modules.conf
tun

Configuration does not support video model 'qxl'

This is usually the case, if QEMU is built without the spice USE flag. To resolve this issue, try to build QEMU with the correct USE flag.

First add spice to via a package.use file:

文件 /etc/portage/package.use/qemu
app-emulation/qemu spice

Then recompile the QEMU:

root #emerge --ask --changed-use app-emulation/qemu

QEMU has kvm support on some guest CPU architectures

KVM only works for the same CPU architecture. An ARM64 host cannot handle x86_64 instructions.

Invalid context errors on SELinux systems

By default, libvirt generates a random SELinux MCS label for the QEMU process, when it is started. If the loaded SELinux policy does not support MCS categories, the resulting security context will be invalid:

代码 SELinux error from virt-manager
Error starting domain: unable to set socket security context 'system_u:system_r:svirt_t:s0:c123,c456': Invalid argument
代码 SELinux error from the kernel
kernel: SELinux: Context system_u:object_r:svirt_image_t:s0:c123,c456 is not valid (left unmapped).

The solution is, either to switch to one of the policy types, which supports MCS categories or manually set the virtual machine's security labels, without MCS categories:

代码 Libvirt domain XML with manually specified seclabel fields
<domaintype="kvm">
<name>fedora</name>
...
<devices>
<disktype="file"device="disk">
<drivername="qemu"type="qcow2"/>
<sourcefile="/var/lib/libvirt/images/fedora.qcow2">
<seclabelmodel='selinux'relabel='yes'>
<label>system_u:object_r:svirt_image_t</label>
</seclabel>
</source>
<targetdev="vda"bus="virtio"/>
<addresstype="pci"domain="0x0000"bus="0x04"slot="0x00"function="0x0"/>
</disk>
...
<seclabeltype='static'model='selinux'relabel='yes'>
<label>system_u:system_r:svirt_t</label>
</seclabel>
</domain>

Static-user and LTO

GCC will use a huge amount of RAM, if LTO is enabled on the system, if any of the ppc64 options are enabled, while using the static-user USE flag. Because of this, it is recommended to disable LTO, while compiling in this configuration or use Clang if LTO is required. See bug #883419

lto1: internal compiler error: original not compressed with zstd

This is caused by a mismatch of GCC, where qemu is compiled against sys-libs/zlib and dev-libs/glib . This can be fixed, by recompiling both libraries, before recompiling app-emulation/qemu again:

root #emerge --ask --oneshot sys-libs/zlib dev-libs/glib
root #emerge --ask --oneshot app-emulation/qemu

Windows guests fail to provision, boot or Blue Screen of Death (BSOD) on startup

For optimal performance, it is recommended, that modern Windows guests (at least Windows 10 22H2 and up) run under a kernel with CONFIG_KVM_HYPERV enabled. If this Kernel driver is not enabled, VMs will fail to provision, to boot or run into a Blue Screen.

Later versions of Windows, if running as virtual machines, sometimes attempt to access hardware registers - specifically MSRs (Model Specific Registers) - that are not actually defined for the emulated processor within the virtual environment. This is often, due to how Windows interacts with hardware, a driver trying to be overly clever or even bugs within the operating system itself. While these MSR accesses might be valid on physical processors, the virtualized environment presented by KVM may not support them.

KVM's default behavior is to attempt to emulate these MSR accesses, but when encountering an undefined register, it reports an invalid instruction error to the virtual Windows instance. This error is often fatal, resulting in a Blue Screen and halting the virtual machine.

提示
unhandled rdmsr or unhandled wrmsr messages in the system logs of the host indicate attempts to access undefined MSRs. Failures may also be more obvious, like failed to set MSR and Assertion `ret == cpu->kvm_msr_buf->nmsrs' failed from qemu-system-*.

An alternative is passing the kernel parameter kvm.ignore_msrs=1 on the kernel command line or as a parameter to the kvm module:

警告
This parameter should only be set, if there are still undefined MSRs. If there are any, then it is probably a bug, which needs to be reported to the software vendor or KVM/QEMU maintainers.
文件 /etc/modprobe.d/kvm.conf
options kvm ignore_msrs=1

The ignore_msrs parameter instructs KVM to ignore any attempts by the virtual Windows machine to access these undefined MSRs. Instead of generating an error and causing a Blue Screen, KVM silently bypasses the problematic instruction. This allows Windows to continue running, albeit potentially with some minor performance implications or masked underlying issues.

附注
While the parameter ignore_msrs can be a quick fix for a decent amount of Blue Screens related to MSR accesses, it is likely, that this can be addressed properly, by enabling the appropriate kernel parameter, as documented above.

Removal

Unmerge

root #emerge --ask --depclean --verbose app-emulation/qemu
附注
There may be image files left behind after the removal of the QEMU package.

See also

External resources

References