Author: Siro, Mugabi

Category: qemu

Summary:

This entry discusses Linux guest configuration for serial port system console on QEMU. Development platform used was Ubuntu 12.04 AMD64.

Tags: qemu linux arm

Preliminaries

Linux System Console

The system console is the device which recieves all kernel messages/warnings and which allows logins in single user mode. The QEMU PC and QEMU ARM Versatile Express platforms will be used here for illustration purposes.

QEMU Serial Port Device Alternatives

The standard serial port devices by QEMU are emulations of standard Universal Asynchronous Receiver Transmitter (UART) devices, and the examples presented here make use of this device.

QEMU also includes support for serial device alternatives such USB-to-UART emulation and virtio-serial which could just as well be used here. For examples of Linux guest configuration and QEMU commandline options for these alternative serial port devices, check out Using QEMU Character Devices and QEMU-virtio.

Guest Configuration

Kernel Support

Linux-PC

For the PC platform, enabling support for console on 8250/16550 and compatible is required to use the serial port as a system console and to allow logins through it. This applies for both the qemu-system-i386 and qemu-system-x86_64 machines.

CONFIG_SERIAL_8250_CONSOLE=y

Linux-ARM

For the Versatile, Integrator/PP2 and Integrator/CP platforms, support for console on the PrimeCell PL011 UART will need to be enabled:

CONFIG_SERIAL_AMBA_PL011=y
CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y

Linux Boot Messages

In order to display Linux boot messages on the serial port system console, console=ttySn (PC) or console=ttyAMAn (ARM Vexpress), where n is 0, 1, ..., should be specified on the Linux commandline. See Documentation/serial-console.txt for examples on more elaborate settings for the serial port console= parameter. Note that inclusion of the quiet boot parameter on the Linux commandline will override any console settings i.e. no kernel boot messages will get displayed.

Enabling Serial Port Login Terminal

Traditionally, login via a serial port terminal required getty(8) settings for the serial port terminal in /etc/inittab.

For example:

[root@buildroot ~]# cat /etc/inittab
...
# Buildroot's default inittab for Busybox.
id:1:initdefault:
...
1:1:respawn:/sbin/getty 38400 tty1
2:1:respawn:/sbin/getty 38400 tty2
S0:1:respawn:/sbin/getty -L ttyS0 115200 vt100 # GENERIC_SERIAL
...

However, this may result in conflicts if there exists some other configuration that manages serial port login. For instance, in the OpenEmbedded platform of this Linaro release, there exists the /etc/init.d/auto-serial-console utility that handles auto-login via serial terminal. An attempt to include, say:

root@genericarmv7a:~# cat /etc/inittab
# The default runlevel.
id:5:initdefault:
...
S0:2345:respawn:/sbin/getty -L ttyAMA0 115200 vt100 
...

will break serial port terminal login.

For Upstart configurations e.g. Ubuntu Karmic and newer:

$ cat /etc/init/ttyS0.conf

# ttyS0 - getty
#
# This service maintains a getty on ttyS0 from the point the system is
# started until it is shut down again.

start on stopped rc or RUNLEVEL=[12345]
stop on runlevel [!12345]

respawn
exec /sbin/getty -L 115200 ttyS0 vt102

Also check out Ubuntu Serial Console HowTo.

In addition to the above getty(8) settings, the corresponding device file settings will also have to be present e.g:

[root@buildroot ~]# ls /dev/ttyS*
/dev/ttyS0  /dev/ttyS1  /dev/ttyS2  /dev/ttyS3

root@genericarmv7a:~# ls /dev/ttyAMA*
/dev/ttyAMA0  /dev/ttyAMA1  /dev/ttyAMA2  /dev/ttyAMA3

Consult Documentation/serial-console.txt for more information on configuring the system for serial port login.

QEMU Commandline

-serial DEV

The -serial DEV option redirects the QEMU guest virtual UART I/O to the host device, i.e. backend, DEV. Note that -serial DEV is legacy commandline syntax (and most examples in this entry still use it). For examples of using the newer commandline syntax check out Redirecting QEMU Serial Line Terminals.

The default DEV is VC in graphical mode (i.e. a QEMU Virtual Console on its SDL window) and stdio in nographic mode. See qemu(1) for the complete listing of legal DEV values. This option can be specified multiple times to emulate upto 4 serial ports. To obtain more than 4 serial ports per guest, consider using virtio-serial.

Graphical mode

By default, the virtual UART I/O is redirected to a QEMU virtual console (VC) which is accessible via CTRL+ALT+N (where N is 2, 3,... depending on your particular setup).

To specify a different host device for the QEMU serial port such as stdio, use -serial stdio.

Guest system console only on virtual UART

  • System console on serial port VC:

    $ qemu-system-i386 -enable-kvm -kernel bzImage -hda test.img -append "root=/dev/sda2 console=ttyS0 rw"
    

    Here, the Linux boot messages get directed to the serial port VC and no boot messages will appear on the default VGA VC.
    In other words, while the (splash screen and) login prompt will eventually appear on the guest (framebuffer) console on the VGA VC, this interface will not be used as the guest system console:

    VC video/default console

    and typing CTRL+ALT+3 to switch to the serial port VC:

    VC serial console

  • Guest system console on stdio:

    $ qemu-system-i386 -enable-kvm -kernel bzImage -hda test.img -append "root=/dev/sda2 console=ttyS0 rw" -serial stdio
    

    Once again, Linux boot messages will not get displayed on the default VGA VC. Here, the messages get redirected to stdio of the launch terminal:

    console on stdio

Guest system console on both VGA VC and virtual UART

In order to use both the VGA VC and virtual UART as the guest system console, specify console=tty0 and a serial port console= setting e.g. console=ttyS0 (PC) or console=ttyAMA0 (Versatile).

Typically, in this scenario, it is more useful to use a host device such as stdio for the guest serial port system console rather than the default QEMU serial port VC. For instance, to use stdio for the guest serial port system console:

$ qemu-system-i386 -enable-kvm -kernel bzImage -drive file=test.img -append "root=/dev/sda2 console=tty0 console=ttyS0 rw" -serial stdio

serial system console on VGA and stdio

As can be seen, guest boot messages appear on both the QEMU VGA VC and the QEMU launch terminal (stdio). It is also possible to login the guest using either interface.

Check out the Redirecting QEMU Serial Line Terminals entry for examples on using other host devices for a guest system console.

Nographic mode

Running QEMU with -nographic completely disables any graphical output (QEMU machine video). To obtain a system console, the virtual UART can be used. In this mode, emulated UART I/O is redirected to the host's stdio by default.

Examples:

  • PC

    $ qemu-system-i386 -enable-kvm -kernel bzImage -drive file=test.img -append "root=/dev/sda2 console=tty0 console=ttyS0 rw" -nographic
    
    [    0.000000] Initializing cgroup subsys cpuset
    [    0.000000] Initializing cgroup subsys cpu
    [    0.000000] Linux version 3.5.1 
    (...)
    Starting SMB services: done
    Starting NMB services: done
    Starting atd: OK
    INIT: Entering runlevel: 1
    
    Welcome to Buildroot
    buildroot login: root
    [root@buildroot ~]# tty
    /dev/ttyS0
    
  • Vexpress

    $ sudo qemu-system-arm -M vexpress-a9 -cpu cortex-a9 -kernel uImage-git -drive file=oe-alip_vexpress.img,if=sd -net nic -net tap,ifname -append "root=/dev/mmcblk0p2 vga=normal rw console=ttyAMA0" -nographic
    
    [    0.000000] Booting Linux on physical CPU 0x0
    [    0.000000] Linux version 3.12.0+ 
    ...
    Starting auto-serial-console: done
    Stopping Bootlog daemon: bootlogd.
    
    Last login: 18:44:17 UTC 
    root@genericarmv7a:~# tty
    /dev/ttyAMA0
    

Note that omitting console=ttyS0 or console=ttyAMA0 (or similar) will result in no boot messages getting displayed. However, the guest serial terminal should eventually kick in with a login prompt, e.g:

$ qemu-system-i386 -enable-kvm -kernel bzImage -hda test.img -append "root=/dev/sda2 rw" -nographic

Welcome to Buildroot
buildroot login:

For examples on using other host devices for a guest serial port system console, see Redirecting QEMU Serial Line Terminals.

A note on nographic mode and guest Linux FB

Booting in nographic mode will succeed even if the guest system was configured with (default) framebuffer console.

For example, booting against the following setup which employed Linux FB by default:

$ qemu-system-arm -M vexpress-a9 -cpu cortex-a9 -kernel uImage -drive file=oe-alip_vexpress.img,if=sd -append "root=/dev/mmcblk0p2 vga=normal rw console=ttyAMA0" -nographic

resulted in:

(...)
[    3.255762] VFS: Mounted root (ext4 filesystem) on device 179:2.
[    3.261067] devtmpfs: mounted
[    3.271918] Freeing unused kernel memory: 332K (c05e0000 - c0633000)
INIT: version 2.88 booting
Starting udev
(...)
root@genericarmv7a:~# ls /sys/class/vtconsole/
vtcon0  vtcon1
root@genericarmv7a:~# cat /sys/class/vtconsole/vtcon0/name
(S) dummy device
root@genericarmv7a:~# cat /sys/class/vtconsole/vtcon0/bind 
0
root@genericarmv7a:~# cat /sys/class/vtconsole/vtcon1/name
(M) frame buffer device
root@genericarmv7a:~# cat /sys/class/vtconsole/vtcon1/bind 
1

But, of course, an attempt to run an application that uses the framebuffer will not result in any graphical output.

On the other hand, booting with fbcon=map:-1 to disable FB console1:

$ sudo qemu-system-arm -M vexpress-a9 -cpu cortex-a9 -kernel uImage -drive file=oe-alip_vexpress.img,if=sd -append "root=/dev/mmcblk0p2 vga=normal rw console=ttyAMA0 fbcon=map:-1" -nographic
(...)
[    3.491841] VFS: Mounted root (ext4 filesystem) on device 179:2.
[    3.496871] devtmpfs: mounted
[    3.508180] Freeing unused kernel memory: 332K (c05e0000 - c0633000)
INIT: version 2.88 booting
Error cannot mmap framebuffer : Invalid argument
Starting udev
(...)
root@genericarmv7a:~# ls /sys/class/vtconsole/
vtcon0
root@genericarmv7a:~# cat /sys/class/vtconsole/vtcon0/name
(S) dummy device
root@genericarmv7a:~# cat /sys/class/vtconsole/vtcon0/bind 
1

Multiplexing guest serial port system console and HMI on stdio

Graphical mode

The QEMU Human Monitor Interface (HMI) console is available, by default, on a QEMU VC (accessible via CTRL+ALT+N, where N is 2, 3... depending on your particular setup). To multiplex the guest serial port system console and the QEMU monitor console on stdio, the -serial mon:stdio option is used. An attempt to use -serial stdio -monitor stdio instead will result in resource conflict e.g:

$ qemu-system-i386 (...) -append "root=/dev/sda2 rw console=ttyS0" -monitor stdio -serial stdio
chardev: opening backend "stdio" failed: Device or resource busy
qemu: could not open serial device 'stdio': Success

Below are a few examples of using -serial mon:stdio:

## PC
$ qemu-system-i386 -enable-kvm -kernel bzImage -hda test.img -append "root=/dev/sda2 console=tty0 console=ttyS0 rw" -serial mon:stdio

## Vexpress
$ qemu-system-arm -M vexpress-a9 -cpu cortex-a9 -kernel uImage -drive file=oe-alip_vexpress.img,if=sd,cache=writeback -append "root=/dev/mmcblk0p2 vga=normal console=tty0 console=ttyAMA0  rw" -serial mon:stdio

For instance, the qemu-system-arm commandline above enabled the following QEMU monitor and guest serial port system console multiplexing on stdio:

serial system console multiplex

Check out the QEMU HMI entry for tips on using the the monitor console.

Nographic mode

Default nographic mode, i.e. -nographic, implies that both HMI and UART I/O for guest system console are automatically multiplexed on stdio. Nevertheless, -serial mon:stdio may still be included on the QEMU commandline as a safe bet.

Also See

Resources

  • qemu(1)

Footnotes

1. See Documentation/fb/fbcon.txt [go back]