Using QEMU inside a terminal with serial output
Posted on 2019-02-27 (Updated on 2019-02-27)
I often have a need for a quick virtual machine. Many of them don't require any video output, so having a virtual monitor is a little overkill. Luckily, with a few QEMU switches and brief configuration of the guest VM, you can view console output in a standard terminal on the host system.
To do this, I create a serial device on the guest machine, and tell QEMU to
send serial output to stdout
on the host machine - which is received by the
terminal you start QEMU in.
You can create this serial device in two ways. The first way would be to define a serial console at the kernel level, through boot arguments specified in GRUB (or however your particular guest sends kernel arguments). This allows you to see boot messages real-time, and may allow for easier debugging, but it's a little more challenging.
If you don't need boot feedback, and just want simple output, you can skip to the second method, use systemd to start a serial console.
Kernel-level serial console
To start, you need to make the following changes to /etc/default/grub
:
GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,38400n8"
GRUB_TERMINAL=serial
GRUB_SERIAL_COMMAND="serial --speed=38400 --unit=0 --word=8 --parity=no --stop=1"
You also need to make sure the serial
package is installed, as it might not be
by default.
Once you have made these changes, you need to run this command before these arguments will be applied to your boot loader:
grub-mkconfig -o /boot/grub/grub.cfg
systemd serial console
If you don't have any interest in boot messages, there is a systemd unit that can be enabled that starts a serial console:
systemctl enable serial-getty@ttyS0.service
systemctl start serial-getty@ttyS0.service
The ttyS0
serial device was the only serial device I set up on my virtual
machines, so you may have to specify a different device if you have multiple
serial ports.
You can list all of your serial ports by running ls /dev/ttyS*
, of course.
QEMU & host terminal setup
After you have the guest set up with a serial console, you need to change some QEMU flags and a couple terminal settings on the host. I wrap it in a script to keep things simple.
#!/usr/bin/env bash
# Save current terminal settings (for restoring later)
STTY_SETTINGS="$( stty -g )"
# Override Ctrl+c and Ctrl+z to prevent killing the VM in horrid ways
# ( Set to right bracket, can be changed if that combination is used )
stty intr ^]
stty susp ^]
qemu-system-x86_64 -nographic -monitor none -serial stdio [...]
# Reset the terminal
stty "$STTY_SETTINGS"
This setup comes in very handy when I need a special purpose VM, but not a whole emulated VGA screen of fuzzy text. If your terminal supports colors, all of the text should come through with your preferred color scheme and everything!
Tags: linux