Skip to content
Fragmented Development

Using QEMU inside a terminal with serial output

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_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

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

Add Your Comment