The Linux keyboard driver
Keycodes are converted to keysymbols by looking them up on the appropriate keymap. There are eight possible modifiers (shift keys), and the combination of currently active modifiers and locks determines the keymap used.
Thus, what happens is approximately:
int shift_final = shift_state ^ kbd->lockstate; ushort *key_map = key_maps[shift_final]; keysym = key_map[keycode];
The eight modifiers are known as Shift, AltGr, Control, Alt, ShiftL, ShiftR, CtrlL and CtrlR. These labels have no intrinsic meaning, and the modifiers can be used for arbitrary purposes, except that the keymap for the Shift modifier determines the action of CapsLock (and that the Shift key partially suppresses keyboard application mode). By default Shift is bound to both Shift keys and Control keys and Alt and AltGr are bound to the left and right Alt keys. The remaining four modifiers are unbound in the default kernel. X is able to distinguish ShiftL and ShiftR, etc.
Thus, there are 256 possible keymaps—for plain symbols, for Shift+symbol, for Ctrl+AltL+Shift+symbol, etc. Usually, not all of the keymaps will be allocated (combinations with more than three modifiers are rather unusual), and in fact the default kernel allocates only 7 keymaps, namely the plain, Shift, AltR, Ctrl, Ctrl+Shift, AltL and Ctrl+AltL maps. You can allocate more keymaps simply by filling some of their entries using loadkeys(1).
Key symbols are shorts, i.e., they consist of two bytes. In Unicode mode, this short is just the 16-bit value returned—or, to be precise, the returned byte string is the UTF-8 representation of this Unicode character. The keyboard is put into Unicode mode by
ioctl(0, KDSKBMODE, K_UNICODE);
When not in Unicode mode, the high order byte is viewed as a type, and the low order byte as a value, and we do:
type = KTYP(keysym); (*key_handler[type])(keysym & 0xff, up_flag);
The type selects a function from the array key_handler:
static k_hand key_handler[16] = {
do_self, do_fn, do_spec, do_pad, do_dead,
do_cons, do_cur, do_shift, do_meta, do_ascii,
do_lock, do_lowercase, do_ignore, do_ignore,
do_ignore, do_ignore
};
do_self, commonly used for ordinary keys, just returns the given value, after possibly handling pending dead diacriticals.
do_fn, commonly used for function keys, returns the string func_table[value]. Strings can be assigned using loadkeys(1).
do_spec is used for special actions, not necessarily related to character input. It does spec_fn_table[value]();, where
static void_fnp spec_fn_table[] = { do_null, enter, show_ptregs, show_mem, show_state, send_intr, lastcons, caps_toggle, num, hold, scroll_forw, scroll_back, boot_it, caps_on, compose, SAK, decr_console, incr_console, spawn_console, bare_num };The associated actions (and their default key binding) are:
Return (Enter): return a CR and if VC_CRLF mode set also a LF. One sets/clears CRLF mode by sending ESC [ 20 h or ESC [ 20 l to the console.
Show_Registers (AltR-ScrollLock): print the contents of the CPU registers.
Show_Memory (Shift-ScrollLock): print current memory usage.
Show_State (Ctrl-ScrollLock): print the process tree.
Break (Ctrl-Break): send a Break to the current tty.
Last_Console (Alt-PrintScrn): switch to the last used console.
Caps_Lock (CapsLock): toggle the CapsLock setting.
Num_Lock (NumLock): in keyboard application mode: return ESC O P; otherwise, toggle the NumLock setting. One sets/clears keyboard application mode by sending ESC = or ESC > to the console. (See also Bare_Num_Lock below.)
Scroll_Lock (ScrollLock): stop/start tty—roughly equivalent to ^S/^Q.
Scroll_Forward (Shift-PageDown): scroll console down.
Scroll_Backward (Shift-PageUp): scroll console up. These two functions are implemented by using the memory on the video card, and provide only a very limited scrollback facility. Moreover, all scrollback information is lost when you switch virtual consoles. So, for real scrollback use a program-like screen.
Boot (Ctrl-AltL-Del): reboot. If you press Ctrl-AltL-Del (or whatever key was assigned the keysym Boot by loadkeys) then either the machine reboots immediately (without sync), or init is sent a SIGINT. The former behavior is the default. The default can be changed by root, using the system call reboot(): see ctrlaltdel(8) and init(8).
Some versions of init change the default. What happens when init gets SIGINT depends on the version of init used—often it will be determined by the pf (stands for powerfail) entry in /etc/inittab, which means that you can run an arbitrary program. In the current kernel, Ctrl-AltR-Del is no longer by default assigned to Boot, only Ctrl-AltL-Del is.
Sometimes when init hangs in a disk wait (and syncing is impossible) it can be useful to say ctrlaltdel hard, which may allow you to force a reboot without power cycling or pressing the reset button.
aps_On (none): set CapsLock.
ompose (Ctrl-.): start a compose sequence. The two following characters will be combined. This is a good way to get accented characters that you only rarely need. For example, Ctrl-.><,><c will produce a c-cedilla, and Ctrl-.>:<a><e the Danish letter æ. Precisely which combinations combine to what character; will show dumpkeys(1), loadkeys(1) will set combinations.
SAK (none): Secure Attention Key. This is supposed to kill all processes related to the current tty, and reset the tty to a known default state. It is not completely implemented—it is not quite clear what resetting the keyboard/console should do to the fonts and keymaps. The easiest solution is to send a signal to some trusted daemon, and let it reset keyboard and console as desired. In this way we obtain something closely related to the Spawn_Console function below.
Decr_Console (AltL-LeftArrow): switch to the virtual console that precedes the current console in the cyclic order.
Incr_Console (AltL-RightArrow): switch to the virtual console that follows the current console in the cyclic order.
Spawn_Console or KeyboardSignal (AltL-UpArrow): send a specified process a specified signal. I use this to signal init that it should create a fresh virtual console for me.
Bare_Num_Lock (Shift-NumLock): toggle the NumLock setting (regardless of keyboard application mode).
As long as no new releases of init and loadkeys have come out, you can play with this by using loadkeys and starting the program spawn_console:
% loadkeys >> EOF alt keycode 103 = 0x0212 EOF % spawn_console &
Of course, if you put this in /etc/rc.local, you would probably want to start getty instead of bash.
do_pad, commonly used for the keypad keys. In keyboard application mode this produces some three-character string ESC O X (with variable X depending on the key), provided that Shift is not pressed simultaneously. Otherwise, when NumLock is on, we get the symbol printed on the key (0123456789.+ -/* and CR).
Finally, if NumLock is not on, the four arrow keys yield ESC [ X (with X=A, B, C, or Dp when not in cursor key mode, and ESC O X otherwise, while the remaining keys are treated as function keys, and yield the associated string. For the middle key (keypad-5) we find four possibilities:
in keyboard application mode (unshifted), ESC O u
in keyboard application mode, shifted, without NumLock, ESC O G
otherwise, without NumLock, ESC [ G
but with NumLock, 5.
If you think this is unnecessarily complicated, I agree. It is a messy combination of VT100 and DOS keyboard behavior. However, so far suggestions for change have met with too much resistance.
do_dead is used for “dead keys” that provide the following key with a diacritical. By default there are no dead keys. One may define keys producing a dead grave, acute, circumflex, tilde, or diaeresis. How a dead key combines with a following key is specified using the compose mechanism discussed above.
do_cons is used for switching consoles. By default the combinations (Ctrl-)AltL-Fn switch to virtual console n for n in the range 1-12, and AltR-Fn switches to console n+12 for these same n.
do_cur handles cursor keys. One gets either ESC [ X or ESC O X (with X one of A, B, C, or D) depending on the cursor key mode. (One sets or clears cursor key mode by sending ESC [ ? 1 h or ESC [ ? 1 l to the console.)
do_shift maintains the shift state (the up/down state of the modifier keys).
do_meta is commonly used for ordinary keys combined with AltL. If the keyboard is in metamode, this will yield a pair ESC x; otherwise x | 0x80 is produced, where x is the key pressed in both cases. (You can set or clear metamode using the tiny utility setmetamode(1).)
do_ascii is used to construct given codes: press AltL, type a decimal code on the keypad, and release AltL. This yields the character with the given code. In Unicode mode the same works in hexadecimal: press AltR, type a hexadecimal code on the keypad, possibly using the ordinary a, b, c, d, e, and f keys, and release AltR. This yields the Unicode symbol with the code given.
do_lock toggles the state of the corresponding modifier key lock. (Recall the line we saw above: shift_final = shift_state ^ kbd-<lockstate.) Thus, if you have your Cyrillic keys under combinations with AltR, you can use AltR together with other keys to get only a few Cyrillic symbols, but should type AltGr_Lock if you plan to type a longish Cyrillic text. (Note that the right Alt key, that I called AltR here, is usually known as AltGr.)
do_lowercase is used for the handling of CapsLock. Note that CapsLock is different from ShiftLock. With ShiftLock, a digit 4 will be turned into a dollar sign (for default keyboard layout), but CapsLock will only affect lower case letters, and turn them into the corresponding upper case letters. Type 11 is equivalent to type 0, with the added information that the symbol may be affected by CapsLock (and the resulting character is the one that would have resulted from pressing Shift).
As already mentioned, almost all of this can be changed dynamically by use of loadkeys(1). The current state is dumped by dumpkeys(1). A list of known symbols is provided by dumpkeys -l. The keycodes associated with the various keys can be found using showkey(1). These and many other utilities for keyboard and console can be found in kbd-0.90.tar.gz on ftp.funet.fi and its mirror sites.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
- Dynamic DNS—an Object Lesson in Problem Solving
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Using Salt Stack and Vagrant for Drupal Development
- New Products
- Drupal Is a Framework: Why Everyone Needs to Understand This
- Validate an E-Mail Address with PHP, the Right Way
- A Topic for Discussion - Open Source Feature-Richness?
- Download the Free Red Hat White Paper "Using an Open Source Framework to Catch the Bad Guy"
- New Products
- The Secret Password Is...
- myip
3 hours 13 min ago - Keeping track of IP address
5 hours 4 min ago - Roll your own dynamic dns
10 hours 17 min ago - Please correct the URL for Salt Stack's web site
13 hours 29 min ago - Android is Linux -- why no better inter-operation
15 hours 44 min ago - Connecting Android device to desktop Linux via USB
16 hours 12 min ago - Find new cell phone and tablet pc
17 hours 11 min ago - Epistle
18 hours 39 min ago - Automatically updating Guest Additions
19 hours 48 min ago - I like your topic on android
20 hours 34 min ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
how to test power and ptt keys??
Hai i want to test power and ptt keys. I am using evtest to test my keys on the keypad. But my driver wont generate any interrupt for power and ptt keys so how to test these keys??
general awareness
general awareness
Getting keyboard scancodes
The article is confused.
Please write a simple non-blocking function.
This can be the prototype:
bool keypressed( int& scancode );
bye
miro
linux keypad driver
the scancode related information are good
Re : Kernel Korner: The Linux keyboard driver
Good One !! But really missing the source code as example.
Re: Kernel Korner: The Linux keyboard driver
It's better to explain with a practical keyboard source code.
Re: Kernel Korner: The Linux keyboard driver
can u pls send the c code for keyboard device driver
need c code of keyboard driver
i will be greatful if someone help me. i need c code fo generic keyboard driver.
Can you please send me
Can you please send me source code of a generic keyboard driver?
Need it for Windows/Dos environment
Hi
I need to access certain keys on a Pentuim PC keyboard using ISO. But ISO just specifies the H and no C files and it only gives you the CRT device not the keyboard-subdevice of the CRT.
So I've decided to do a search for keyboard-drivers. And now I want the complete c code for a keyboard driver, please?
Re: Kernel Korner: The Linux keyboard driver
not a practical example... too confuse
Yes you are right
Linux needs to simplify everything so that our grandparents can use the system easily. I bet my grandparents would prefer Microsoft keyboard like http://www.compkeyboard.com/archives/microsoft-natural-ergonomic-keyboar...
than a Linux system with 4 pages of tutorial on keyboard
Dude, your an idiot. Your
Dude, your an idiot. Your grandparents are very unlikely to be writing keyboard drivers for Linux or Windows.
Grandparents
Oh, yeah? Well, my grandparents are awesome like that: 'Cept they write drivers for *nix only!
key state
getchar() is a blocking call and when you press a button the corresponding character is output to the terminal. Would if all I wanted was the state of any given key at any given time? Doing this on PS2 Linux is quite easy with the js0 device for composing a bit-feild containing the state of each controller button this frame. Is their a non-blocking, non-printing way to obtain the key state of any given key?
Source code for keyboard.c in on your computer
If you install the kernel source code you can find the source
code in /usr/src/linux/drivers/char/keyboard.c