2015년 2월 12일 목요일

Notes on connecting to systems using a serial console cable

In my day job, I sometimes encounter ATCA hardware that doesn't have any external video ports. In these cases, I have to connect to the machine using a USB to RS232 serial console cable with DB9 connectors like the one pictured below:



along with a DB9 to RJ45 Cisco serial console cable:



The RJ45 end of the Cisco cable plugs into the ATCA serial console port.

Below are some tips for connecting to machines using serial console cables from a Linux host.


1. Verify that your Linux host is correctly detecting your USB-to-Serial device

First, check the output of journalctl -f (systemd) or tail -f /var/log/messages (non-systemd) and make sure that something like the following appears once you connect your USB-to-Serial cable:

[root@localhost ~]# journalctl -f
-- Logs begin at Wed 2014-12-17 16:39:00 KST. --
...
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: new high-speed USB device number 8 using xhci_hcd
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: New USB device found, idVendor=0403, idProduct=6010
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: Product: Dual RS232-HS
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: Manufacturer: FTDI
Dec 17 17:26:17 localhost.localdomain mtp-probe[10169]: checking bus 2, device 8: "/sys/devices/pci0000:00/0000:00:14.0/usb2/2-3"
Dec 17 17:26:17 localhost.localdomain mtp-probe[10169]: bus: 2, device: 8 was not an MTP device
Dec 17 17:26:17 localhost.localdomain kernel: usbcore: registered new interface driver ftdi_sio
Dec 17 17:26:17 localhost.localdomain kernel: usbserial: USB Serial support registered for FTDI USB Serial Device
Dec 17 17:26:17 localhost.localdomain kernel: ftdi_sio 2-3:1.0: FTDI USB Serial Device converter detected
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: Detected FT2232H
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: Number of endpoints 2
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: Endpoint 1 MaxPacketSize 512
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: Endpoint 2 MaxPacketSize 512
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: Setting MaxPacketSize 512
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: FTDI USB Serial Device converter now attached to ttyUSB0
Dec 17 17:26:17 localhost.localdomain kernel: ftdi_sio 2-3:1.1: FTDI USB Serial Device converter detected
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: Detected FT2232H
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: Number of endpoints 2
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: Endpoint 1 MaxPacketSize 512
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: Endpoint 2 MaxPacketSize 512
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: Setting MaxPacketSize 512
Dec 17 17:26:17 localhost.localdomain kernel: usb 2-3: FTDI USB Serial Device converter now attached to ttyUSB1
...

In my case, since my USB-to-Serial cable has two connectors, my host has allocated /dev/ttyUSB0 and /dev/ttyUSB1 to each of the DB9 interfaces. We can verify this by looking at /sys/class/tty below:

[centipete@localhost ~]$ ls /sys/class/tty
console  tty1   tty13  tty17  tty20  tty24  tty28  tty31  tty35  tty39  tty42  tty46  tty5   tty53  tty57  tty60  tty7   ttyS1    ttyUSB1
ptmx     tty10  tty14  tty18  tty21  tty25  tty29  tty32  tty36  tty4   tty43  tty47  tty50  tty54  tty58  tty61  tty8   ttyS2
tty      tty11  tty15  tty19  tty22  tty26  tty3   tty33  tty37  tty40  tty44  tty48  tty51  tty55  tty59  tty62  tty9   ttyS3
tty0     tty12  tty16  tty2   tty23  tty27  tty30  tty34  tty38  tty41  tty45  tty49  tty52  tty56  tty6   tty63  ttyS0  ttyUSB0

To find the driver being used by the USB-to-Serial interface, let's take a look at the output of dmesg shortly after connecting the console cable:

[centipete@localhost ~]$ sudo dmesg |tail -n 20
[sudo] password for centipete:
[ 2836.672274] usb 2-3: New USB device found, idVendor=0403, idProduct=6010
[ 2836.672280] usb 2-3: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 2836.672283] usb 2-3: Product: Dual RS232-HS
[ 2836.672285] usb 2-3: Manufacturer: FTDI
[ 2836.808456] usbcore: registered new interface driver ftdi_sio
[ 2836.808481] usbserial: USB Serial support registered for FTDI USB Serial Device
[ 2836.808536] ftdi_sio 2-3:1.0: FTDI USB Serial Device converter detected
[ 2836.808570] usb 2-3: Detected FT2232H
[ 2836.808572] usb 2-3: Number of endpoints 2
[ 2836.808574] usb 2-3: Endpoint 1 MaxPacketSize 512
[ 2836.808575] usb 2-3: Endpoint 2 MaxPacketSize 512
[ 2836.808576] usb 2-3: Setting MaxPacketSize 512
[ 2836.808693] usb 2-3: FTDI USB Serial Device converter now attached to ttyUSB0
[ 2836.808711] ftdi_sio 2-3:1.1: FTDI USB Serial Device converter detected
[ 2836.808746] usb 2-3: Detected FT2232H
[ 2836.808749] usb 2-3: Number of endpoints 2
[ 2836.808751] usb 2-3: Endpoint 1 MaxPacketSize 512
[ 2836.808753] usb 2-3: Endpoint 2 MaxPacketSize 512
[ 2836.808755] usb 2-3: Setting MaxPacketSize 512
[ 2836.810205] usb 2-3: FTDI USB Serial Device converter now attached to ttyUSB1

Using lsmod, let's make sure that this driver has been loaded by the kernel:

[centipete@localhost ~]$ lsmod |grep ftdi
ftdi_sio               48889  0

We could also look at the output of lsusb to verify that the USB-to-serial cable is connected, but this is unnecessary because we already know that the kernel has detected it and loaded the proper driver.


2. Connect to the remote machine using a serial communications program

Most of my fellow engineers at Growin use minicom, but putty and GNU Screen also work just fine.

Minicom
If you decide to use minicom, invoke it with minicom -s (--setup) and set the proper console speed. For ATCA machines, it is usually either 57600 or 115200 bps, but you should just use the speed the ATCA hardware engineer tells you to use (the console speed can be set in the ATCA BIOS).

In more recent versions of minicom (version 2.7-1 is installed on my machine as of 2015-02-12) you can access the options menu by pressing 'Ctrl-a' followed by 'z'. Make sure the terminal emulation (option 't') is set to ANSI (VT100), not VT102. For some reason, my default setting was VT102 and even with the correct speed setting, minicom just showed gibberish until I changed to VT100.

minicom may be overkill for what you are trying to do, however, and it is also finicky.

Putty
If you use Putty, you are asked to enter the speed settings and other comm parameters before connecting. On the left-hand scroll menu, select 'Serial' at the very bottom and enter the correct parameters in the following window:



If you are using a USB to Serial cable, don't forget to change the serial interface name to /dev/ttyUSB0 or whatever your kernel decides to name it.

GNU Screen
By far the easiest way to connect to another machine by serial console cable is screen. At first, I assumed tmux would also have this feature, but it does not, as its developer thinks such a function would be feature bloat. Thankfully, screen supports serial console connections and it is as easy as invoking the following:

[archjun@lenovoS310 ~]$ sudo screen /dev/ttyUSB0 57600

That's it! No fiddling with flow control, parity, etc. It just works as long as you specify the interface name /dev/tty... and the console speed in bps. I only recently learned that screen has this awesome feature while watching Canonical's Dustin Kirkland connecting to a BeagleBone ARM board using a USB-to-TTL serial console cable. In the Youtube video below at 4:34, Dustin uses screen to connect to the BeagleBone by invoking

sudo screen /dev/ttyUSB0 115200


There are other serial communication programs you can use (on Windows there are a variety of commercial programs like XShell, SecureCRT, etc) but I find GNU Screen to be the simplest way to connect to a serial console!