|
Keyboards should be one of the easiest peripherals to interface to, however in practice they turn out to be very complex. This is mainly because each part of the system tries to be too clever, and so the downstream part of the keyboard handler has to be even more complex to undo the `intelligence' of the previous component. Here we discuss how keyboards are handled under Linux, some of the problems this introduces, and what you can do to get round them. Start at the fundamentals. The keyboard itself consists of a number of keys. Each key is given a key number, which simply identifies its location on the keyboard. The keys are scanned, unusually by a small microcontroller. When a key press is detected, the keyboard sends a scan code to the host. Most keyboards send two scan codes for each key, a make code when the key is pressed down, and a break code when the key is released. This allows the host to detect if a modifier key (for example shift) is still held down when a second key is pressed. Unfortunately PS/2 keyboards take things a step further and further complicate things. Note that these keyboards are bidirectional, you can send commands to the keyboard as well as receive data from them (I won't go into how, except to say that IBM didn't increase the number of wires to the keyboard, so the clock and data lines are bidirectional - you can see why the keyboard has to have its own microcontroller - usually a mask programmed 8042). In particular:
That covers the keyboard itself. Most computers these days have a dedicated keyboard controller. Again this is frequently a small microcontroller (originally also an Intel 8042). Again this is bi-directional, with commands being set to the keyboard controller itself, and replies received, as well as communicating with the keyboard. We have finally reached the first layer of software on the host computer. This is the keyboard device driver, which manages the keyboard controller. On a PC this is the file pc_keyb.c, which accesses the keyboard registers through a couple of macros. The Hitachi support chip, the HD64465, also provides a PS/2 compatible interface. However rather than use the keyboard controller used on a PC, Hitachi have implemented a much thinner interface, where the keyboard driver has to have much more intelligence, and in particular writing to the keyboard, and arbitrating access, has to be done in software. To implement this within the Linux kernel and still allow the normal keyboard driver to be used, an additional software layer fakes up the normal keyboard controller registers in software. This is done in the hd64465_keyb.c file. The next higher level of software handles the scncode to keycode mapping. This is performed partly by the generic driver code in keyboard.c and partly in the low level keyboard driver, either pc_keyb.c or for generic_keyb_trans.c. The next level above this handles the keycode to action mapping, in vc.c. Linux console can be in one of four modes:
The keyboard mode is set using the KDSKBMODE ioctl and read by the KDGKBMODE ioctl. X WindowsThe keyboard driver for use under Linux is in the file .../xc/programs/Xserver/hw/kdrive/linux/keyboard.c. This puts the keyboard into MEDIUMRAW mode, whereby keycodes are used directly. Mapping in then performed internally to the X keycodes. In order to determine which keys should be mapped, the code also reads the keyboard translation table (as dumpkeys does) using the KDGKBENT ioctl.
|
|||||||||||||||||||||
|
||||||||||||||||||||||