NEXT UP previous
Next: Modems

Console Terminal

For most Linux systems there will be only one user and the main access to the system will be via the machine's keyboard and screen - the console terminal. In fact the console terminal is really two separate peripheral devices: a screen/video output device and keyboard input device. As we shall see, for both of these devices there is quite a bit of setting up which can be performed.

Keyboard Input

The keyboard on a PC seems to be a relatively simple device - it is a box with buttons on it, the buttons are numbered and lettered, you press a button, the appropriate character is displayed on the screen. However, despite the apparent simplicity, there is an awful lot more going on than would seem to be the case at first glance.

To start with, many countries that use PCs need odd extra characters in their character sets in order to be able to cope with the quirks of different spoken languages. This means that many keyboard variations exist, with minor differences in layout and content.

It is much cheaper in a manufacturing sense to be able to produce a single keyboard in terms of its electronics and physical construction and just change the symbols on some of the key-tops, than it is to produce new electronics for each keyboard variation. In order to get this to work, however, it is necessary to have some kind of lookup arrangement so that a single key in a particular physical position on the keyboard can generate different byte values to match the key top on the key.

In Linux, this lookup is done in software inside the kernel in the keyboard driver. Effectively, there is a table in the kernel which gives the byte values to generate for each of the keys on the keyboard and also for the combinations of each key with the various Ctrl, Shift and Alt keys.

Each physical key on the keyboard is given a unique keycode number in the range 1 to 127. A keyboard map file is then used to specify what byte values are to be generated for each keycode or keycode combination you press. By default, the keyboard map files are stored in the directory:

	/usr/lib/kbd/keytables

Keyboard map files are normally loaded into the kernel at system boot time using the loadkeys command. So, for example, to load the map file for a UK keyboard you would use the command:

	$ /usr/bin/loadkeys /usr/lib/kbd/keytables/uk.map

This command needs to be entered into one of the system startup files. These are normally stored somewhere under the directory /etc (though exactly where under /etc can vary with different Linux distributions) and have names of the form:

	rc.XXX

where XXX indicates what the file is used to configure. Under the Slackware distribution the loadkeys command appears in the file:

	/etc/rc.d/rc.keymap

The keyboard map files themselves are just ordinary text files so you can easily view and edit them if you wish to create your own keyboard mappings for special purposes. If you only want to change the mappings of a few keys on top of some otherwise standard layout, then you only need to create a map for the changes, which you can then load after the standard layout has already been set up.

In order to find out what the keycodes are for the keys whose functions you want to change, you need to use the showkey command. When this command is running, any key you press or release will cause its keycode to be displayed. In order to terminate the showkey program, it is arranged so that it will automatically exit if you don't press any keys for ten seconds:

	$ showkey
	press any key, program terminates after lOs of last keypress
	keycode	28	release
	keycode	25	press
	keycode	25	release
	keycode	46	press
	keycode	46	release
	$

Once you know the keycodes that you want to change, it is a simple matter to modify a keyboard map file appropriately and then load it. The format of the map files is quite straightforward and a good description of it is given in the manual page:

	$ man 5 keytables

You may wish to modify the keyboard map table in the kernel incrementally, until you are happy with the way it operates. In these circumstances you can generate a map file for subsequent loading from the current kernel table with the dumpkeys command, as follows:

	$ dumpkeys >newkey.map

Video Output

Just as with the keyboard, the screen output also has some lookup tables associated with it, whose values can be altered for special purposes, or just for fun!

Normally, when a byte is sent to the screen, its 8-bit value is used as the code for the character to display. It is possible, however, to insert a translation table into this sequence. This table is just a simple 256-element array of bytes. With this table in use, any time a byte is sent to the screen in order to display the character it represents, what happens is that the byte is used as an index into the table to select one of the 256 elements. It is the 8-bit value in that array element which actually specifies the byte value to display. If, by default, the table is set up so that:

	table[O] = 0
	tableEl] = 1
	table[2] = 2
            -
            -
	table[255] = 255

then this has the same effect as when the table isn't there at all. Changing any of the values from the default automatically allows translations to be made from one character to another as they are displayed.

In order to modify the output translation table you use the mapscrn command:

	$ mapscrn filename

where filename is the name of the file which contains the new character mappings. Once the table has been set up, it can be enabled by sending a special character sequence to the display. This sequence is the Esc character followed by '(K'. Use of the translation table can subsequently be disabled by replacing the K in the enable sequence with a B.

The manual page for the mapscrn command gives a full description of the formats in which translation entries may be specified in the translation file, but, basically, they all boil down to giving a list of character pairs which specify a character followed by its new translation. A simple example will help to clarify the point.

Suppose for some reason you wanted to translate any of the upper case letters W, X and Y into an asterisk (*). The translation file to specify this could have the contents:

	'W' '*'
	'X' '*'
	'Y' '*'

This file (called, say, newtab) could then be loaded into the console display driver with the command:

	$ mapscrn newtab

The easiest way to send the special escape sequence to the console driver to enable the character translations is with the following echo command:

	$ echo -e '\033(K'

After sending this sequence, any attempts to send W, X or Y to the screen will result in the display of an asterisk, as the following command sequence illustrates:

	$ echo -e '\033(K' VWXYZ
	 V***Z
	$ echo -e '\033(B' V***Z
	 VWXYZ

Obviously, in the second echo command, where the three asterisks appear, I actually typed WXY but, because of the translations, they didn't come out that way.

The other table which appears in the display sequence is actually stored on your video card and its contents control the appearance of the displayed characters themselves. Changing the contents of this table allows you to change displayed fonts. Many character fonts are available for Linux and it is also a straightforward (if a little tedious) task to generate your own custom character and graphic shapes.

First, in order to load up one of the standard fonts, you use the setfont command and specify the name of a font file:

	$ setfont sc.fnt

where sc.fnt is the name of the font file to load. If you try it, you will find that sc.fnt is quite a fun font, though you probably wouldn't want to use it all the time. By default, the font files are stored in the directory:

	/usr/lib/kbd/consolefonts

In order to understand the contents and layout of a character font file, we need to take a simplified look at the mechanics of displaying text characters. On a VGA screen when it is displaying 25 lines of text that are 80 characters long, each character occupies a pixel grid on the screen which is eight pixels wide and 16 pixels high.

Next, each displayable character is made up of a set of lit and unlit pixels, also on an 8x16-pixel grid. To display a particular character on the screen in a particular position, all that is required is to copy the pixels from the correct character grid into the appropriate pixel grid position on the screen.

In the character grids, a pixel is represented by a single bit which just specifies whether the corresponding pixel is lit or unlit. This means that an easy way to store the pixel information for a complete 8x16-pixel grid is just as a set of 16 single-byte values - 1 byte for each 8-pixel row in the grid. Figure 1. shows a typical pixel grid for the letter A and the set of 16 byte values (in hex) that result.

As you can see, the example letter A has a grid which is encoded as:

	00 00 10 38 6c c6 c6 fe c6 c6 c6 c6 00 00 00 0O

You have already seen that characters sent for display arrive as numbers in the range 0 to 255 (i.e. 256 in total). A complete 8x16-pixel character set, then, is made up of 256 different 8x16-pixel grids. A font file for an 8x16-pixel character set just contains the 256 sets of 16 bytes, one after the other to create a file 4096 bytes long.

Creating your own character set and font file is just a case of working out pixel grids for each of the characters, sorting out the 16 single byte values for each grid and then writing these values away to a file which you can subsequently load with the setfont command and use.

In addition to font files that are 4096 bytes long, you may well find that you have some files of different lengths. In general, these other files contain characters with pixel grids that are 8x8 pixels or 8x14 pixels instead of the 8x16 pixels you have just seen. These other character sets are intended for use in different screen resolution modes or with different graphics adaptors (like EGA). There are still 256 different characters in these other character sets and the pixel rows are still stored as bytes in the same way; there are just less rows to each character. This means that the size of these other font files will be 2048 bytes for 8x8-pixel character sets and 3584 bytes for the 8x14-pixel character sets.

Just to add a final touch of complexity, there is also another font file type which the setfont program can use. This other type has exactly the same layout that you have already seen except that there are 4 bytes of header information in the file as well, which makes these files 4 bytes bigger than the files we have considered previously. This makes the full list of file sizes:

	2048 bytes
	2052 bytes
	3584 bytes
	3588 bytes
	4096 bytes
	4100 bytes

From the file size, setfont can work out what the file type is and what the file format is as well.


NEXT UP previous
Next: Modems