JRDN
Jason Roysdon dot Net

Serial port redirection to console in Linux

March 5th 2010 in Linux, Security

There are times when keyboard and video monitor access (KVM) is not always accessible or scalable. Serial port redirection to console is a way to be able to access hosts before booting the OS in Linux.

I will discuss 3 different steps that are needed to accomplish this in Linux.

Note: KVM in this article references "keyboard and video monitor". KVM will not be referencing Kernel-based Virtual Machine in this article.

You need to know what serial port you are connected to. What my BIOS calls Serial Port 1, DOS/Windows calls COM1, Linux calls /dev/ttyS0, and I will reference here as Serial0. You also need to know what BAUD rate, or speed, your serial port supports and the device you are connected to it. 9600 BAUD is always safe, but very slow. You can start there, and increase the speed until things break. 115200 BAUD is typically the fastest you can run.

  • Step 0: The BIOS

This step may not apply to you at all, so I am calling it Step 0. You either have this in your BIOS or you do not. All is not lost if you don't, you just can't see the POST, go into the BIOS or SCSI controller settings. Skip this step if your BIOS doesn't mention console or serial redirection.

I do have a system where the BIOS allows me to do Console Redirection. This allows me to see the POST before even reading from the hard drive. This is useful as I could turn on PXE network booting or CD-ROM booting remotely, see a failed hard drive that won't boot, run diagnostics from my SCSI controller, etc..

lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqwqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk
x Intel  Xeon  Processor                  x BIOS Version: A02                  x
x Processor Speed: 2.80 GHz               x Service Tag :                      x
mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqvqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj
lqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk
x                                                                              x
x System Memolqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqk DDR2    a x
x Video Memorx Console Redirection .............. Serial Port 1    x         a x
x System Memox Failsafe Baud Rate ............... 115200           x           x
x Redundant Mx Remote Terminal Type ............. VT100/VT220      x           x
x            x Redirection After Boot ........... Disabled         x           x
x OS Install mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj           x
x CPU Information ......................................                       x
x                                                                              x
x Boot Sequence ........................................                       x
x Hard-Disk Drive Sequence .............................                       x
x USB Flash Drive Emulation Type ....................... Floppy                x
x                                                                            a x
x Integrated Devices ...................................                     a x
x PCI IRQ Assignment ...................................                     a x
x                                                                            a x
x Console Redirection ..................................                       x
mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj
  Up,Down Arrow to select  x  SPACE,+,- to change  x  ESC to exit  x  F1=Help

I should note that for Step 1 to succeed below, you must turn off BIOS redirection after boot or Grub won't be able to access the serial port.

  • Step 1: Grub pre-menu

In /etc/grub.conf you can add these two lines:

serial --unit=0 --speed=115200
terminal --timeout=5 serial console

The first line is just setting the serial port and speed. --unit=0 references my Linux Serial0. --speed=115200 is setting the BAUD to 115200.

In the second line, the terminal --timeout option waits 5 seconds for you to press a key on either the real keyboard (which GRUB calls the "console") or the serial port. GRUB doesn't know where you want to control it from yet. Where ever you press the key first will get control. Or, after the terminal --timeout value it will use the first listed option, which in my example is the serial port.

After the BIOS POST, I see:

Press any key to continue.
Press any key to continue.
Press any key to continue.
Press any key to continue.
Press any key to continue.

Unless I press a key and then it will stop and take me to the GRUB menu, which is Step 2.

  • Step 2: Grub menu

If I don't press any key in Step 2, and the Grub menu timeout expires (not to be confused with the terminal --timeout option), I will then see the following on my serial terminal:

  Booting 'CentOS (2.6.18-164.11.1.el5) - Serial console'

But if I press SPACEBAR or just about any key (not ENTER which would take the default option), I'll see the Grub menu:

    GNU GRUB  version 0.97  (640K lower / 1047296K upper memory)

 +-------------------------------------------------------------------------+
 | CentOS (2.6.18-164.11.1.el5) - Serial console                           |
 | CentOS (2.6.18-164.11.1.el5) - Video console                            |
 |                                                                         |
 +-------------------------------------------------------------------------+
      Use the ^ and v keys to select which entry is highlighted.
      Press enter to boot the selected OS or 'p' to enter a
      password to unlock the next set of features.

From the serial terminal I have to use the ^ (SHIFT-6) and v (lower-case v as Victor) to navigate. If I were seeing the Grub menu on the real keyboard console, I'd use the regular arrow keys.

So by default your /etc/grub.conf should have something like this in it:

title CentOS (2.6.18-164.11.1.el5)
 root (hd0,0)
 kernel /vmlinuz-2.6.18-164.11.1.el5 ro root=/dev/blah
  initrd /initrd-2.6.18-164.11.1.el5.img

What I do is duplicate this entry and make modifications:

title CentOS (2.6.18-164.11.1.el5) - Serial console
 root (hd0,0)
 kernel /vmlinuz-2.6.18-164.11.1.el5 ro root=/dev/blah console=ttyS0,115200
 initrd /initrd-2.6.18-164.11.1.el5.img
title CentOS (2.6.18-164.11.1.el5) - Video console
 root (hd0,0)
 kernel /vmlinuz-2.6.18-164.11.1.el5 ro root=/dev/blah
 initrd /initrd-2.6.18-164.11.1.el5.img

I use the first menu item for my serial terminal, and add to the title "Serial console." I add to the end of the kernel line "console=ttyS0,115200" which sets it to use my Linux Serial0 with BAUD rate 115200.

I use the second menu item for my regular keyboard console, and add to the title "Video console". I won't modify the kernel line and leave the rest of it stock.

So to recap, whichever place I want to control things, I press SPACEBAR during the Press any key to continue. terminal --timeout. Then, during the Grub menu timeout I press SPACEBAR again. In reality, I just keep pressing SPACEBAR until I see the Grub menu appear.

Then, whichever option I choose and press ENTER for in the Grub menu, that will determine where my Linux kernel booting will appear.

But after it boots, I won't see anything on my serial terminal until shutdown. I want to be able to login on my serial terminal as well.

  • Step 3: Serial login access with agetty

In order to get a serial terminal running once the Linux kernel boots, you need to have a line in inittab:

s0:2345:respawn:/sbin/agetty -L -f /etc/issue.serial 115200 ttyS0 vt100

After adding this line, execute init q to have inittab re-read and start the serial terminal without rebooting. After booting this will always take place.

This tells inittab to start the first serial terminal (s0) with during runlevels 2-5, using agetty, displaying /etc/issue.serial, using 115200 BAUD with /dev/ttyS0 and vt100 as the terminal type.

Using /etc/issue.serial is not required, you could just use /etc/issue but I like to create a custom /etc/issue.serial and display the serial port and BAUD rate that I am connected to.

I do this by copying the stock /etc/issue and adding a few lines:

cp -a /etc/issue /etc/issue.serial
echo "Connected on \l at \b bps" >> /etc/issue.serial
echo "\U" >> /etc/issue.serial

The \l displays the serial port and \b displays the BAUD (bits per second). \U displays the number of users logged in.

So after booting the kernel, my serial console displays:

CentOS release 5.4 (Final)
Kernel 2.6.18-164.11.1.el5 on an x86_64

Connected on ttyS0 at 115200 bps
0 users

Eagle.roysdon.net login:

There you have it. Steps 0 - 4 are not dependent on each other. But if you want to see what is going on from power on to power off, you need all of them.

One final hack that I use for my co-located servers: I have two servers at the same co-location, and no remote KVM access. Should one of them fail during boot-up, I can SSH to the one that is online, and use minicom to connect to Serial 1 which has a null-modem cable connected to Serial 0 on the opposite server.

[Server 1]Serial0 - nullmodem - Serial1[Server 2]

[Server 1]Serial1 - nullmodem - Serial0[Server 2]

This means that I can use minicom on either server to connect out Serial1 to the Serial0 on the other server. Serial0 on each server is using the serial port redirection mentioned above.

Here some settings I change in Minicom and have stored in my /etc/minirc.serial configuration file:

pu port             /dev/ttyUSB1
pu minit
pu mreset
pu escape-key       ^B

The first option tells Minicom to use my USB Serial port 1. I have a dual-serial port USB, which gives me /dev/ttyUSB0 and /dev/ttyUSB1. I have a DB9 female-nullmodem-DB9 female cable connected to /dev/ttyUSB1.

The second option blanks out the modem init string. This changed the default minicom behavior that sends AT init string. The third option blanks out the modem reset string instead of the default minicom behavior that sends an ATZ string. I don't want either of getting sent to my Linux consoles.

Next I change the default escape key from CTRL+a to CTRL+b. My Adaptec SCSI controller and the Linux screen command both use CTRL+a, I don't want to have to remap it in screen, so I remap it in Minicom.

To start this /etc/minirc.serial configuration file, I execute minicom serial.

One final note is that you can use this method for remote PXE installs that you don't want to script completely, but cannot run VNC for some reason. Using VNC is the best option, as software raid and perhaps some other options aren't available in the anaconda installer when using text.

Simply put text console=ttyS0,115200 on your kernel linux of your PXE configuration file.


One comment to...
“Serial port redirection to console in Linux”
stephen

Awesome! Thank you so much for this! This was very very helpful.




required



required - won't be displayed


Your Comment:

So you want to make the leap on to the interwebs [sic], I mean webtubes [sic], something bigger than your FaceSpace, err, MyBook, you know those social-thing-a-ma-bobs, right? But you don't have big enough pipes coming to your house? What do you do?

Previous Entry

If you have your own domain, like roysdon.net, you may at some point want to be able to login to a webpage, receive and send email, transfer files with ftp, and even vpn. But the trick is to do this securely. Secure Sockets Layer, or SSL, is the means to accomplish this.

Next Entry