Installing Debian on QEMU virtual serial port console

Most commonly the guides for installing (GNU/)Linux distributions in virtual machines such as QEMU (+KVM) involve using emulation of a graphics display. This is most likely because it’s convenient, and most installation programs default to using VGA display on PCs.

While this is mostly effortless, there are a few drawbacks. VNC requires listening a TCP port or a Unix socket on the server. If configure the VNC server to listen a TCP port, anyone can connect, so be sure to set a decent password for the VNC server. Still, even if you set a decent password, a security-conscious administrator might not want to expose that TCP port at all, possibly even locally. If you use a Unix socket, it’s a pain to use the VNC connection if the network throughput is limited. Even the VNC protocol does require a lot more network throughput to be usable than just a remote shell on a terminal would.

The alternative is to switch to a virtual serial port as soon as possible in the installation. Most distributions do not support installation through a serial port out of the box, but BIOS may support VGA emulation on a serial console. That’s right; you get what you’d see on a VGA display to a serial port. Only text modes are supported, naturally. In Debian, the package offering such a BIOS ROM option is sgabios.

This guide expects you’re also using libvirt.

Enabling serial console and serial port VGA emulation on a virtual machine

First, install the sgabios package:

apt-get install sgabios

Then, add the following line to the os section of the QEMU virtual machine’s libvirt domain:

<bios useserial='yes'/>

This enables VGA text mode emulation for a serial port. Enabling the serial port itself and serial console is achieved by adding the following entries to the devices section of a libvirt domain:

<serial type='pty'>
  <target port='0'/>
  <alias name='serial0'/>
</serial>
<console type='pty'>
  <target type='serial' port='0'/>
  <alias name='serial0'/>
</console>

Edit 2018-04-12: In addition to adding the above lines, you will need to remove existing console definitions.

Installation

These instructions are for Debian stable. The same approach is likely to work on other distributions as well.

Set up the virtual serial port as instructed above, and start the installer. I don’t elaborate that as there are plenty of good guides for that. Use virsh to connect to the virtual serial port after starting the domain:

virsh console domain

You should see the first messages from BIOS or the boot loader, depending on how fast you connect to the domain’s console after starting the domain. You may also see nothing at all until you push the arrow buttons.

Debian installer on virtual serial port with sgabios VGA emulation

The arrow keys don’t appear to work very well. Select the item you want, i.e. non-graphical installation. Don’t press enter yet, instead press tab. This lets you to set kernel’s command line options. Remove “— quiet” and replace it with

console=ttyS0 vga=none

And press enter. You should be able to continue the installation normally now.

Once the packages and the boot loader are installed, do not reboot the system yet. We still need to configure the boot loader to use the virtual serial console. Choose to go back, and then execute a shell:

Bind mount the virtual file systems under /target and chroot to /target:

mount -o bind /proc /target/proc
mount -o bind /sys /target/sys
mount -o bind /dev /target/dev
chroot /target /bin/bash

Permanently enabling serial port console for Grub and Linux kernel

Setting the kernel command line to include the serial console earlier only allowed installing Debian, but the serial console configuration now needs to be made permanent. That can be done by changing Grub configuration:

nano /etc/default/grub

Replace the two lines here in the default configuration (in two different locations of the file):

GRUB_CMDLINE_LINUX=""
#GRUB_CONSOLE=console

with these, respectively:

GRUB_CMDLINE_LINUX="console=ttyS0"
GRUB_CONSOLE=serial

Finally, refresh the active grub configuration:

update-grub

And you’re done! The next time you reboot the virtual machine, it should start off with the console available on the serial port right from the beginning.

Finishing the installation

If you were installing Debian, unmount the file systems you mounted and return to the installer:

exit # to exit the chroot environment
umount /target/sys /target/dev /target/proc
exit # to get back to the installer

Now we’re ready to proceed to reboot the system.

The installation is now complete and you can boot from the virtual disk, with virtual serial console enabled.

Leave a comment