How does one set up a serial terminal and/or console in Red Hat Enterprise Linux?

Updated -

Introduction

It is sometimes helpful to have a serial console for debugging purposes and a serial terminal for headless operation. A serial console will send all console output to the serial port. A serial terminal, if properly configured, also lets you log on to the system via the serial port as a remote terminal. You can set up both or just one. This article will cover the configuration of serial terminals in RHEL.

Contents

Serial Console Kernel Option Configuration

First, to get the kernel to output all console messages to the serial port you need to pass the console=ttyS0 (please note that the trailing character is a zero, not the letter O) parameter to the kernel at boot time. This is usually done via the bootloader; we'll be using GRUB in our examples. The following example will configure the system to send the console output to the serial port ttyS0 at a baud rate of 115200 as well as sending the output to the regular console or "screen" tty0.

  • Edit the file /boot/grub/grub.conf by adding the following kernel options to the kernel line:

    console=ttyS0,115200 console=tty0
    
  • For example, in grub.conf:

    [root@localhost ~]# cat /boot/grub/grub.conf
    # grub.conf generated by anaconda
    #
    # Note that you do not have to rerun grub after making changes to this file
    # NOTICE:  You have a /boot partition.  This means that
    #          all kernel and initrd paths are relative to /boot/, eg.
    #          root (hd0,0)
    #          kernel /vmlinuz-version ro root=/dev/hda2
    #          initrd /initrd-version.img
    #boot=/dev/hda
    default=0
    timeout=10
    splashimage=(hd0,0)/grub/splash.xpm.gz
    title Red Hat Enterprise Linux AS (2.4.21-27.0.2.ELsmp)
            root (hd0,0)
            kernel /vmlinuz-2.4.21-27.0.2.ELsmp ro root=LABEL=/ console=ttyS0,115200 console=tty0
            initrd /initrd-2.4.21-27.0.2.ELsmp.img
    
  • Note: Regarding the above documented baud rate 115200, the baud rate for a given configuration depends upon the hardware settings. Each server will have its own serial console settings, generally noted in the system BIOS. Before applying any such settings, it is recommended that you also check your server manual. Incorrectly configured baud rate settings might lead to junk character being displayed at login.

  • Note: The primary console for system output will be the last console listed in the kernel parameters. In the above example, the VGA console tty0 is the primary and the serial console is the secondary display. This means messages from init scripts will not go to the serial console, since it is the secondary console, but boot messages and critical warnings will go to the serial console. If init script messages need to be seen on the serial console as well, it should be made the primary by swapping the order of the console parameters:

    console=tty0 console=ttyS0,115200
    
  • Any settings altered in grub.conf will take effect on the next system reboot.

  • One will also have to add the serial port to the /etc/securetty file in Red Hat Enterprise Linux 4, 5, and 6 to allow root logins through the serial port. ttyS0 should be added to the bottom of the list on a new line:

    tty9
    tty10
    tty11
    ttyS0
    
  • Red Hat Enterprise Linux 7 has a ttyS0 entry in /etc/securetty by default.

Serial Terminal Configuration in RHEL 4 and RHEL 5

This configuration will set up the serial port as a remote terminal, allowing logins via the serial console. To do this we need to spawn an agetty process for the serial port.

  • This is achieved by adding the following line to the /etc/inittab file:

    co:2345:respawn:/sbin/agetty ttyS0 115200 vt100
    
  • This option should be added to the the section called # Run gettys in standard runlevels:

    # Run gettys in standard runlevels
    1:2345:respawn:/sbin/mingetty tty1
    2:2345:respawn:/sbin/mingetty tty2
    3:2345:respawn:/sbin/mingetty tty3
    4:2345:respawn:/sbin/mingetty tty4
    5:2345:respawn:/sbin/mingetty tty5
    6:2345:respawn:/sbin/mingetty tty6
    co:2345:respawn:/sbin/agetty ttyS0 115200 vt100
    
  • After this edit is made, run the following command:

    # init q
    

Serial Terminal Configuration in RHEL 6

For RHEL6, upstart (the init process) starts an agetty process automatically if the primary console is the serial port (recall that the last console= parameter is the primary).

  • To start agetty on a serial port that is not the primary console, create a new /etc/init/serial-ttyS0.conf file with the following contents:

    start on stopped rc RUNLEVEL=[2345]
    stop on runlevel [S016]
    
    respawn
    exec /sbin/agetty /dev/ttyS0 115200 vt100-nav
    
  • Then start the new agetty by rebooting or by running

    [root@localhost ~]# initctl start serial-ttyS0
    
  • Note: if the keyboard is not working correctly on the new agetty, you may need to remove console=ttyS0 from the kernel parameters.

    • Some background information:

      • As the system boots, it starts udev to handle hardware devices. The /lib/udev/rules.d/10-console.rules file tells udev to check a number of devices, including /dev/console, and run the /lib/udev/console_check helper program against each device:

        # Console initialization - keyboard, font, etc.
        KERNEL=="tty0",         RUN+="/lib/udev/console_init %k"
        
        # Check and set up serial and serial-like consoles if necessary
        KERNEL=="console",      RUN+="/lib/udev/console_check %k"
        KERNEL=="ttySG*",       RUN+="/lib/udev/console_check %k"
        KERNEL=="xvc*",         RUN+="/lib/udev/console_check %k"
        KERNEL=="hvsi*",        RUN+="/lib/udev/console_check %k"
        KERNEL=="hvc*",         RUN+="/lib/udev/console_check %k"
        
      • If console_check determines that /dev/console is a serial console (by running some ioctl() system calls on it), then it runs this command:

        /sbin/initctl emit --no-wait fedora.serial-console-available DEV=ttyS0 SPEED=115200
        
      • This command sends a fedora.serial-console-available event to the init daemon. The init daemon is configured for this event by /etc/init/serial.conf:

        start on fedora.serial-console-available DEV=* and stopped rc RUNLEVEL=[2345]
        stop on runlevel [S016]
        
        instance $DEV
        respawn
        pre-start exec /sbin/securetty $DEV
        exec /sbin/agetty /dev/$DEV $SPEED vt100-nav
        
      • The init daemon launches agetty by running the command from the exec line in serial.conf:

        /sbin/agetty /dev/ttyS0 115200 vt100-nav
        
      • And this shows the login prompt on the serial console.

  • To check the status of the serial console, use the initctl command to query the init daemon's jobs:

    [root@localhost ~]# initctl list | grep serial
    serial (ttyS0) start/running, process 1254
    
  • Or:

    [root@localhost ~]# initctl status serial DEV=ttyS0
    serial (ttyS0) start/running, process 1254
    
  • Note the DEV=ttyS0 parameter above. Without this parameter, initctl returns a not-very-clear error message:

    [root@localhost ~]# initctl status serial
    initctl: Unknown parameter: DEV
    
  • The DEV=ttyS0 parameter is necessary because of the job definition in /etc/init/serial.conf as shown above.

Serial Terminal Configuration in RHEL 7

  • Add, or update if already present, the following lines to /etc/default/grub:

    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0,115200n8"
    GRUB_TERMINAL=serial
    GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
    
    • GRUB_CMDLINE_LINUX_DEFAULT applies this configuration only to the default menu entry, use GRUB_CMDLINE_LINUX to apply it to all the menu entries.
    • NOTE: each line type above should only appear once within the /etc/default/grub file. If the line already exists, then just modify it rather than add a second copy of same. That is, only one GRUB_CMDLINE_LINUX_DEFAULT line should exist in the file, etc.
  • Rebuild the /boot/grub2/grub.cfg file by running the grub2-mkconfig -o command as follows:

    • On BIOS-based machines: ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
    • On UEFI-based machines: ~]# grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
  • Additional information available in RHEL 7 System Administrator's Guide 26.9. GRUB 2 over a Serial Console

Red Hat Enterprise Linux 8

  • GRUB boot parameters are edited via grub2-editenv command. First, retrieve the current parameters:

    # grub2-editenv - list | grep kernelopts
    kernelopts=root=/dev/mapper/rhel_example-root ro crashkernel=auto resume=/dev/mapper/rhel_example-swap
    rd.lvm.lv=rhel_example/root rd.lvm.lv=rhel_example/swap 
    
  • From here, copy the entire line and append the serial console parameters, and pass this into the noted command above;

    grub2-editenv - set "kernelopts=root=/dev/mapper/rhel_example-root ro crashkernel=auto resume=/dev/mapper/rhel_example-swap rd.lvm.lv=rhel_example/root rd.lvm.lv=rhel_example/swap console=tty0 console=ttyS0,115200"
    
  • The console parameter should now be set. A reboot will be required for the parameter to take effect. The parameters can be listed to confirm the parameter was set:

    # grub2-editenv - list | grep kernelopts
    kernelopts=root=/dev/mapper/rhel_example-root ro crashkernel=auto resume=/dev/mapper/rhel_example-swap
    rd.lvm.lv=rhel_example/root rd.lvm.lv=rhel_example/swap console=tty0 console=ttyS0,115200
    

Red Hat Enterprise Linux 9

  • Modify the kernel parameters using grubby command .

  • Retrieve the current parameters:

       # grubby --info=ALL|grep -i args
    
      # grubby --info=ALL|grep -i args
       args="ro crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M resume=/dev/mapper/rhel-swap rd.lvm.lv=rhel/root      rd.lvm.lv=rhel/swap 
    
  • Update the parametrs "console=tty0 console=ttyS0,115200"

      # grubby --update-kernel=ALL --args="console=tty0 console=ttyS0,115200"
    
  • The console parameter should now be set. A reboot will be required for the parameter to take effect. The parameters can be listed to confirm the parameter was set:

     # grubby --info=ALL|grep -i args
      args="ro crashkernel=1G-4G:192M,4G-64G:256M,64G-:512M resume=/dev/mapper/rhel-swap rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap console=tty0 console=ttyS0,115200"  
     # reboot
     # cat /proc/cmdline
    

Controlling GRUB from a Serial Console

One can also tell grub to use the serial console instead of the VGA console. This lets one interrupt the boot process and choose a different kernel or add kernel parameters, for example, to boot into single user mode.

  • To configure GRUB to use the serial console, comment out the splash image and add the serial and terminal options to grub.conf:

    [root@localhost ~]# cat /boot/grub/grub.conf
    # grub.conf generated by anaconda
    #
    # Note that you do not have to rerun grub after making changes to this file
    # NOTICE:  You have a /boot partition.  This means that
    #          all kernel and initrd paths are relative to /boot/, eg.
    #          root (hd0,0)
    #          kernel /vmlinuz-version ro root=/dev/hda2
    #          initrd /initrd-version.img
    #boot=/dev/hda
    default=0
    timeout=10
    #splashimage=(hd0,0)/grub/splash.xpm.gz
    serial --unit=0 --speed=115200
    terminal --timeout=5 serial console
    title Red Hat Enterprise Linux AS (2.4.21-27.0.2.ELsmp)
            root (hd0,0)
            kernel /vmlinuz-2.4.21-27.0.2.ELsmp ro root=LABEL=/ console=ttyS0,115200 console=tty0
            initrd /initrd-2.4.21-27.0.2.ELsmp.img
    
  • Any settings altered in grub.conf will take effect on the next system reboot.

Comments