In this text I explain how to configure a Linux server so that it can be used with a serial terminal (like the Qume qvt101). This document is not Linux distribution-specific, and applies to any recent distribution that uses agetty (other getty programs should work too, but program's parameters may differ).
During my second week at De Nayer institute I noticed a big pile of old computers at the supplies department. Among those old computers were an Apple II, early PC-AT's, 486's and old monitors. One of my interests are old computers. The mainframe-era has something mystical about it, huge computer rooms (saunas) with big tape streamer's, and lots of green phosphor CRT terminals (and their predecessors the teletypes).
After carefully inspecting those devices I noticed that two of the monitors were terminals actually, instead of video cables they had RS-232 ports on them and, as a quick test concluded, they seemed to be still alive when plugged in the wall. When I asked some staff member that was passing by if it was OK if I took a terminal home, he seemed to like the idea of me taking the entire pile of junk better, which was unfortunately quite impractical. Riding the train with a monitor under your arm is hard enough (which turned out doable since the terminal wasn't that heavy), I doubt a big pile of old computers would fit under my arm...
Getting it to work
It took me a couple of days to get the thing working. It turned out that there was a good reason the keyboard was retired, most of the keys didn't work anymore. I found a PDF file with some information about the QVT-101+ on the internet (it's a good source of information although the QVT101 PLUS is different in many ways). The manual said that it was possible to get into the configuration menus by pressing CTRL-SHIFT-SETUP.
So the next day I found myself going through the pile of old computer junk again. And fortunately I found another keyboard. When I got home I finally got in the configuration mode and explored the menus, it seems to be more flexible than I thought. The terminal has an online mode, in which the terminal sent all input from the keyboard to the host, and a LOCAL mode, in which it echo's all typed characters on the screen, the second keyboard seemed to have fewer broken keys, and working with it is doable, but still hard.
With some SUBD connectors and wires I hooked the DB25F host connector to my pc's DB9M serial port connector. As the female connector on the terminal indicated, a straight extension cable (not nullmodem) was needed to connect the terminal to a pc. I managed to display the characters sent from the terminal in minicom (like hyperterminal), and characters sent from minicom(the pc) on the terminal's screen.
I didn't have a extension cable with a DB9F and DB25M but only a DB9 extension cable, so I made a DB25M-DB9F converter. I built it into the plastic box of the DB25 connector, and used strong wires so the DB9 connector wouldn't break off if somebody pulled an attached extension cable.
Connecting a serial terminal to a Linux host
The electrical connection between terminal is made with a serial cable. Depending on which brand and type of terminal, a straight extension cable, or nullmodem cable is necessary. If you are using a normal PC as terminal, a nullmodem cable is obligatory, real 'dumb' terminals (like my Qume QVT-101) may require a straight serial extension cable.
There are two ways to use a serial terminal with Linux The first is to pass the kernel a boot parameter instructing it to use ttyS0 as system console. The second way is to let the Linux init system run a getty instance on the system device /dev/ttyS0. A getty is a daemon that connects a tty (teletype) device to a program's standard input/output, it is primarily used to to start the "login" prompt (/bin/login) on the virtual consoles (tty0 to tty5) of a Linux computer.
Other uses of a getty are dailin connections (calls made by some computer TO the Linux host), in which case the getty will start a BBS server program or PPP connection when the modem indicates a phone ring.
Finding out what serial ports you have
To see a list of installed (and found) serial ports on your Linux system run this command:
$ dmesg | grep ttyS ttyS00 at 0x03f8 (irq = 4) is a 16550A ttyS01 at 0x02f8 (irq = 3) is a 16550A
As you can see my server has two serial ports, ttyS00 and ttyS01 (their device nodes are /dev/ttyS0 and /dev/ttyS1). Most motherboards have two serial ports on them. If you don't get any output, you might have them disabled in the BIOS.
Running an extra getty on ttyS[0..?]
I'm assuming the port used is ttyS0, use the same steps if you want more serial terminals on other ports. The first thing you do is take a backup copy of the file we're going to edit, /etc/inittab
# cp /etc/inittab /etc/inittab.bak
Then, add the folowing line to /etc/inittab with your favorite text editor (Vim, nano, gedit, kwrite or the likes) and save it. This line will make the init system start a getty on ttyS0
T0:23:respawn:/sbin/getty -L -n -i -l /bin/bash ttyS0 19200 dumb
When looking at the inittab file, you will notice that for every tty device, a line is included that looks like the one you just added. A short explanation of this line will make it easier to understand what we're doing. Each block is separated by a semicolon(:):
- T0 Identifier used by init. It is unique in the inittab file, as long as this entry doesn't appear anywhere else in inittab, you're okay. We named this entry T0 because it's the first terminal. (for the n-th terminal use Tx, eg. T5 for terminal nr 5)
- 23 Runlevels in which the getty is supposed to run.
- respawn Restart the getty if it dies (it does when the user logs out on that console)
Then there is the command to be started: /sbin/getty -L -n -i -l /bin/bash ttyS0 19200 dumb
Here is a list of getty's parameters I used (taken straight from the agetty manual pages):
-L : Force the line to be a local line with no need for carrier detect. This can be useful when you have locally attached terminal where the serial line does not set the carrier detect signal. -n : Do not prompt the user for a login name. This can be used in connection with -l option to invoke a non-standard login process such as a BBS system. -i : Do not display the contents of /etc/issue other) before writing the login prompt. Terminals or communications hardware may become confused when receiving lots of text at the wrong baud rate -l /bin/bash : Invoke the specified login_program instead of /bin/login. This allows the use of a non-standard login program (for example, one that asks for a dial-up password or that uses a different password file). ttyS0 : the serial device the terminal is connected to 19200 : the communication speed (baudrate) dumb : the type of terminal attached.
And here follows an explanation why I used these parameters.
- -L : It's a local terminal, so it's necessary.
- -n : used with -l option, see below.
- -i : Don't display /etc/issue, that's not needed...
- -l /bin/bash
Normally getty runs the /bin/login program. This asks for a UNIX username and password. If the login is correct, it starts the user's favourite shell (bash for instance). Typing my password is very hard since it contains many special characters (I'm not used to the US layout) and some keys don't work well. By adding -l program, getty will start an other program like /bin/bash instead of /bin/login.
- ttyS0 : the system device the terminal is connected to.
- 19200 : the maximum speed the qvt101 can handle. Note: the standard Linux console uses 38400 baud, which is much faster. You can use another value here, but remember to set the terminal to that speed.
- dumb : the type of terminal attached. This is used by libtermcap and programs like vi, emacs, lynx and screen who handle the terminal in an intelligent way. Normally I should be able to use "qvt101" or "qvt101+" but for some reason libtermcap doesn't know these.
To apply the changes we just made we're going to restart init, and kill all getty's
# telinit q # pkill getty
Then you best check if an extra getty is running on the serial port you wish:
# ps aux bar grep ttyS0
This should list all processes with ttyS0 as parameters or tty.