QEMU
Emulators |
---|
PC Emulators |
PC Virtual Machine Monitors |
PowerPC Emulators |
QEMU is a free and open-source emulator that performs hardware virtualization. It is widely available for variety of host operating-systems and requires minimal configuration for use in operating-system development. It is capable of emulating a wide variety of systems including ARM, x86 and RISC-V, among others. For a more comprehensive list of targets refer to the official documentation.
Features
- Supports multiple hosts, multiple targets.
- Two operating modes: full system emulation (of interest for operating-system development) and Linux user process emulation (of interests to people who want to emulate applications).
- Uses 'just in time' code compilation technique (allowing reuse of previous interpretation). This makes it faster than the popular alternative emulator Bochs.
- Provides native GDB support. QEMU can be attached to GDB/DDD to debug the guest operating-system. Refer to the GDB-Stub section below for more information.
- Supports VBE 2.0.
VBE Support
VBE support be checked by typing 'vbeprobe' on the GRUB command-line. The test returns:
0x101 | Packed pixel | 640x480x8 |
0x110 | Direct Color | 640x480x15 |
0x111 | Direct Color | 640x480x16 |
0x112 | Direct Color | 640x480x24 |
0x103 | Packed pixel | 800x600x8 |
0x113 | Direct Color | 800x600x15 |
0x114 | Direct Color | 800x600x16 |
0x115 | Direct Color | 800x600x24 |
0x105 | Packed pixel | 1024x768x8 |
0x116 | Direct Color | 1024x768x15 |
0x117 | Direct Color | 1024x768x16 |
0x118 | Direct Color | 1024x768x24 |
0x107 | Packed pixel | 1024x768x8 |
0x119 | Direct Color | 1024x768x15 |
0x11A | Direct Color | 1024x768x16 |
Supported Architectures
- x86
- x86_64
- ARM
- ARM64
- LoongArch
- LatticeMico32
- Motorola 68000
- MicroBlaze
- MIPS
- MIPS64
- Moxie
- PowerPC
- PowerPC64
- RISC-V
- IBM System/390
- SuperH
- SPARC
- SPARC64
- TriCore
- Unicore
- Xtensa
Supported Devices
More info: System Emulation Guest Hardware Specifications — QEMU documentation
Non-Display Hardware
- Ne2000 network card
- e1000 network cards
- RTL8139 network card
- AMD PCnet network cards
- PC Speaker
- Sound Blaster 16 sound cards
- AC97
- Intel High Definition Audio
- Virtio devices
- PCI support (With BIOS32).
- QEMU_fw_cfg Allows you to pass info to the guest
Display Adapters
More info: VGA and other display devices in qemu | 🇺🇦 kraxel’s news and Quick overview of every QEMU display adapter in UTM (for x86-based guests) : r/UTMapp
QEMU Device Name | Emulates Real Hardware | Notes | See |
---|---|---|---|
vga | No (except VGA) | QEMU's standard video device. Emulates both the standard 1987-era VGA hardware, as well as the Bochs Display Adapter (which is an easy way to get a framebuffer for your OS if you're not using BIOS/VBE/UEFI). Look for the PCI device with ID 1234:1111 and set registers via PCI MMIO, then access the framebuffer pointed to in the PCI BARs. Alternatively use the VGA port I/O registers, BIOS ROM, and memory area if you're only interested in the VGA compatible hardware and ignore the Bochs extensions. | Bochs VBE Extensions / VGA Hardware |
isa-vga | No (except VGA) | This is the same device as 'vga', but without support for PCI. Access to Bochs extension registers is via port I/O, with the framebuffer hardcoded at 0xE0000000. | Bochs VBE Extensions / VGA Hardware |
bochs-display | No | This is the Bochs display hardware that the 'vga' and 'isa-vga' devices have, but without the VGA hardware backwards compatibility. This hardware will only work with UEFI firmware, as BIOS firmware requires VGA compatibility. | Bochs VBE Extensions |
secondary-vga | No | As far as I can tell this is the same device as 'bochs-display' with a different name, but more research is required. - User:Jackscott | Bochs VBE Extensions |
ramfb | No | A very simple graphics device that just has a framebuffer in memory to write to. | |
vmware-svga | No (except VGA) | VMWare's virtual video hardware, with similar intentions to the Bochs Display Adapter. Unless you're targetting VMWare as a hypervisor platform, this device is largely deprecated. | |
qxl-vga | No (except VGA) | Another virtual-only video card a bit more modern (just) than the Bochs and VMWare devices. It has basic 2D acceleration and multi-monitor support. | |
qxl | No | The same device as the 'qxl-vga' device, but without VGA backwards compatibility. Used mainly for adding secondary video cards to Windows 9x guests. | |
cirrus-vga | Yes | Emulates the Cirrus Logic CLGD 5446 graphics card on the PCI bus. | Technical Reference Manual |
isa-cirrus-vga | Yes | An ISA version of the Cirrus Logic CLGD 5446 graphics card. | Technical Reference Manual |
ati-vga | Yes | Emulates either an ATI Rage 128 Pro ('model=rage128p') or an ATI Radeon RV100 ('model=rv100'). This device is emulated on the AGP bus. |
VirtIO Display Adapters
QEMU Device Name | OpenGL Support? | VGA Compatibility? | PCI Device? | Notes |
---|---|---|---|---|
virtio-gpu-device | No | No | No | |
virtio-gpu-gl-device | Yes | No | No | |
virtio-gpu-pci | No | No | Yes | |
virtio-gpu-gl-pci | Yes | No | Yes | This is the recommended device for modern UEFI operating systems. |
virtio-ramfb | No | ? | Yes | |
virtio-ramfb-gl | Yes | ? | Yes | |
virtio-vga | No | Yes | Yes | |
virtio-vga-gl | Yes | Yes | Yes |
Usage
QEMU does not require the use of a configuration script like Bochs. An example usage of QEMU can be seen below:
qemu-system-i386 \
-accel tcg,thread=single \
-cpu core2duo \
-m 128 \
-no-reboot \
-drive format=raw,media=cdrom,file=myos.iso \
-serial stdio \
-smp 1 \
-usb \
-vga std
When running QEMU on a non-UNIX system, it may be necessary to use the -L command-line option to instruct QEMU where to find a BIOS image.
The -m 128 argument instructs QEMU to create the guest system with 128MB of RAM. The -drive format=raw,media=cdrom,file=myos.iso argument instructs QEMU to create a drive in our guest system. In this case the created drive is a CDROM drive, with myos.iso as its loaded media. If more than one drive in is required in the guest system, it is possible to use the -boot option to define the order in which the system will check for bootable media.
The -serial stdio argument used above instructs QEMU to redirect the serial input and output to the host system's stdio stream. This is particularly useful for debugging purposes. In the documentation, the option to redirect this to stdio is described as Unix only. Presumably, one should be able to achieve a similar effect with -serial file:CON on Windows.
In order to help track down the source of a triple fault, the -d int option can be used to show additional debugging information on interrupts that occur. Additionally, the -no-shutdown and -no-reboot options can be used. These instruct the virtual machine to halt on error instead of rebooting or shutting down, allowing for the operator to inspect the state of the machine after a triple-fault.
Additional useful command-line options are listed within the Useful QEMU command-line options section.
The keyboard shortcuts CTRL-ALT-{1,2,3} can be used inside the emulator to swap in/out of the emulation screen, the QEMU monitor and a serial console. Additional debugging commands can be issued from the system console, such as changing disk images and performing memory dumps, among others.
The debug console
Instead of the serial port, as outlined above, one can also use the debugcon device. By running QEMU with -debugcon stdio, you can print a message to your host system's terminal by just writing each byte to port 0xe9. This is the same port as the one used by the equivalent feature in Bochs.
Unlike the serial port, the debug console is one-way – you can only output. On the flip side, implementing support is much easier, and outputting the messages isn't artificially throttled by a baudrate.
The QEMU monitor
- Main article: QEMU Monitor
QEMU features its own internal 'monitor' console for debugging the guest operating-system. Through various commands, the monitor allows you to inspect the running guest OS, change removable media and USB devices, take screenshots and audio grabs, and control various aspects of the virtual machine. The monitor can be accessed by the key combination CTRL-ALT-2 within QEMU.
It is possible to redirect QEMU's monitor output to stdio using the following command-line option when invoking QEMU:
-monitor stdio
Some useful commands:
- xp
- eXamine Physical memory. Much like GDB's x command, but with no address translation.
- cpu n
- switch to CPU n. Note that GDB's threads are numbered from 1, but QEMU's CPUs are numbered from 0.
- info registers
- dump register state
- info tlb
- Show virtual memory translation state.
- info mem
- Show the page table mappings in a compact form.
- help
- List all commands -- keep in mind that there may be more commands available than those mentioned in the QEMU documentation.
A full list of the capabilities of QEMU's monitor is available in the official documentation as well as here.
Useful QEMU command-line options
Shown below are a list of command-line options for QEMU which are of special significance to Operating-System development. For a full list of options refer to the official QEMU documentation.
Option | Description |
---|---|
-no-reboot | Prevents QEMU from rebooting in the event of a Triple Fault. |
-no-shutdown | Don’t exit QEMU on guest shutdown, but instead only stop the emulation. |
-d | Enables the printing of extra debugging information. Arguments for this option include cpu_reset, int, guest_errors ( among others ). This can be extremely useful when setting up an IDT to see interrupt execution in real-time. |
-gdb or -s | Launches QEMU in GDB Stub mode. This causes QEMU to accept incoming connections from a GDB client. See below for more information or refer to official documentation. |
-S | Causes the guest CPU not to start execution on startup. This is very useful for debugging as it launches the guest in a paused state. The user must use the continue command in the console ( or GDB ) to initiate execution on the guest system. |
GDB-Stub
Starting QEMU with the -gdb or -s <dev> command-line options will instruct QEMU to listen for an incoming GDB connection. By default QEMU will listen for a connection over HTTP on localhost:1234, but the option will accept an argument for a different connection. It is useful to use this switch together with the -S option, which will cause QEMU to start in a paused state. This will allow additional time to connect a GDB client, to start the simulation a continue command will need to be issued within GDB or in the QEMU console.
For convenience, it is also possible to create a file containing commands for GDB to automatically execute. GDB will read and execute the contents of a file with the name .gdbinit in the current working directory. Alternatively, a different file may be specified by the use the -command=file command-line argument. An example file can be seen below:
file <my-kernel-binary>
target remote localhost:1234
# Inspect page tables
x /8wg &page_tables_start
This will automatically load the kernel binary's symbol file into the debugger and then open the remote connection to QEMU.
Ensure that the kernel was compiled with debugging symbols included. This can be accomplished via the use of the GCC option -g. If you find that the debugger can't find local variables, try using the -fno-omit-frame-pointer option during compilation, or disable optimizations.
When running an SMP kernel, the info threads and thread commands can be used to provide useful information. It is also possible to use the QEMU monitor and its commands using the monitor command in GDB. For a list of available commands and their description, use the monitor help command.
Tracing
Tracing in QEMU allows you to view logs for many different peripherals that use the system. You can enable tracing with the argument --trace "prefix*". The prefix depends on the peripheral you're trying to debug.
For example, the AHCI peripheral (hw/ide/ahci.c) uses functions such as ahci_mem_read_ahci. You can enable tracing for this peripheral with the command line argument --trace "ahci_*"
ahci_mem_read_32_host ahci(0x5a1b5d4a6370): mem read [reg:CAP] @ 0x0: 0xc0141f05
ahci_mem_read_32 ahci(0x5a1b5d4a6370): mem read @ 0x0: 0xc0141f05
ahci_mem_read ahci(0x5a1b5d4a6370): read4 @ 0x0: 0x00000000c0141f05
Getting detailed logs
It is possible to enable the output of additional debugging information to stdout by uncommenting certain preprocessor directives within the QEMU source files.
Some files within the QEMU source code have commented lines of the form:
// #define DEBUG_*
Recompiling QEMU from source with this preprocessor variable defined will cause additional debugging information from the applicable file to be printed to stdout.
See Also
Articles
- QEMU and GDB in long mode
- QEMU_fw_cfg Pass strings and files into the VM from the QEMU command line