Difference between revisions of "Understand how keyboards work"

From Linuxintro
imported>ThorstenStaerk
 
(5 intermediate revisions by 3 users not shown)
Line 2: Line 2:
  
 
= The X layer =  
 
= The X layer =  
 +
The X Window system takes the incoming keycodes and reacts on them. Use [[xev]] to see which keyboard events X sees. You can map their keycodes to keys using [[xmodmap]]. For example this makes the right "Windows" key to the [[compose key]]:
 +
xmodmap -e "keycode 134 = Multi_key"
 +
Now every key is mapped to the keyboard layout, e.g. German keyboards look different from English ones. For that X11 has /usr/X11R6/lib/X11/xkb/symbols where the layout "latin" (default one) contains mappings like this:
 +
    key <AD01>  { [        q,          Q,          at,  Greek_OMEGA ] };
 +
    key <AD02>  { [        w,          W,      lstroke,      Lstroke ] };
 +
    key <AD03>  { [        e,          E,            e,            E ] };
 +
    key <AD04>  { [        r,          R,    paragraph,  registered ] };
 +
    key <AD05>  { [        t,          T,      tslash,      Tslash ] };
 +
    key <AD06>  { [        y,          Y,    leftarrow,          yen ] };
  
Use [[xev]] to see which keyboard events X sees.
+
= The tty layer =
 +
The keymappings on tty layer (vs. X Window system) can be changed with the command loadkeys (vs. setxkbmap for X Window system), for example:
 +
# loadkeys us
 +
Loading /usr/share/kbd/keymaps/i386/qwerty/us.map.gz
 +
/usr/share/kbd/keymaps/i386/qwerty # zcat us.map.gz
 +
<pre>
 +
# us.map
 +
keymaps 0-2,4-6,8-9,12
 +
alt_is_meta
 +
include "qwerty-layout"
 +
include "linux-with-alt-and-altgr"
 +
include "compose.latin1"
 +
include "euro1.map"
 +
strings as usual
 +
 
 +
keycode  1 = Escape
 +
keycode  2 = one              exclam
 +
keycode  3 = two              at              at              nul              nul
 +
</pre>
  
 
= The layer beneath X =
 
= The layer beneath X =
 
 
To find out what signals X receives from the keyboard, open a new graphical [http://simple.wikipedia.org/wiki/Command_Line_Interface console] and type
 
To find out what signals X receives from the keyboard, open a new graphical [http://simple.wikipedia.org/wiki/Command_Line_Interface console] and type
 
  cat /dev/tty0
 
  cat /dev/tty0
 
You will see the messages that the kernel (and his modules) put into the tty0 device, the keyboard. When you are ready, close the console with a [[mouse]] click, as because of obvious reasons, you cannot abort with a keypress.
 
You will see the messages that the kernel (and his modules) put into the tty0 device, the keyboard. When you are ready, close the console with a [[mouse]] click, as because of obvious reasons, you cannot abort with a keypress.
 +
 +
= The USB layer =
 +
If you have a USB keyboard you can watch what happens on the USB bus.
 +
* use lsusb to find out what USB bus your keyboard is on
 +
lsusb
 +
* load the kernel module usbmon
 +
modprobe usbmon
 +
* analyse the respective USB bus with WireShark
 +
wireshark
  
 
= The [[kernel]] layer =
 
= The [[kernel]] layer =
 
 
If you really want to see what data comes over the wire, you have to write a [[kernel module]], because the i386's security concept will not let anything read data but the kernel. So, create /root/keyb.c:
 
If you really want to see what data comes over the wire, you have to write a [[kernel module]], because the i386's security concept will not let anything read data but the kernel. So, create /root/keyb.c:
 
  /*  A kernel module.
 
  /*  A kernel module.
Line 23: Line 57:
 
  int init_module(void)
 
  int init_module(void)
 
  {
 
  {
   printk("This is a kernel module\
+
   printk("This is a kernel module\n");
");
 
 
   int retries = 0x100100;
 
   int retries = 0x100100;
 
   int input;
 
   int input;
Line 33: Line 66:
 
  void cleanup_module(void)
 
  void cleanup_module(void)
 
  {
 
  {
   printk(KERN_ALERT "Au revoir\
+
   printk(KERN_ALERT "Au revoir\n");
");
 
 
  }
 
  }
 
and Makefile:
 
and Makefile:
Line 54: Line 86:
 
= See also =
 
= See also =
 
* [[keyboard]]
 
* [[keyboard]]
 +
* [[background: How keyboards work]]
  
 
[[Category:Concept]]
 
[[Category:Concept]]

Latest revision as of 14:12, 16 July 2014

Keyboards typically are connected to the computer via a USB or a PS/2 cable. They send signals when they transfer data, when they acknowledge and when their buffer is full or empty. The kernel receives these signals and, depending on the loaded kernel module (provided the kernel does not do the work itself), sends the data to /dev/tty0. The application (typically X or a shell) gets these signals and puts them into a queue, like stdin.

The X layer

The X Window system takes the incoming keycodes and reacts on them. Use xev to see which keyboard events X sees. You can map their keycodes to keys using xmodmap. For example this makes the right "Windows" key to the compose key:

xmodmap -e "keycode 134 = Multi_key"

Now every key is mapped to the keyboard layout, e.g. German keyboards look different from English ones. For that X11 has /usr/X11R6/lib/X11/xkb/symbols where the layout "latin" (default one) contains mappings like this:

   key <AD01>  { [         q,          Q,           at,  Greek_OMEGA ] };
   key <AD02>  { [         w,          W,      lstroke,      Lstroke ] };
   key <AD03>  { [         e,          E,            e,            E ] };
   key <AD04>  { [         r,          R,    paragraph,   registered ] };
   key <AD05>  { [         t,          T,       tslash,       Tslash ] };
   key <AD06>  { [         y,          Y,    leftarrow,          yen ] };

The tty layer

The keymappings on tty layer (vs. X Window system) can be changed with the command loadkeys (vs. setxkbmap for X Window system), for example:

# loadkeys us
Loading /usr/share/kbd/keymaps/i386/qwerty/us.map.gz

/usr/share/kbd/keymaps/i386/qwerty # zcat us.map.gz

# us.map
keymaps 0-2,4-6,8-9,12
alt_is_meta
include "qwerty-layout"
include "linux-with-alt-and-altgr"
include "compose.latin1"
include "euro1.map"
strings as usual

keycode   1 = Escape
keycode   2 = one              exclam
keycode   3 = two              at               at               nul              nul

The layer beneath X

To find out what signals X receives from the keyboard, open a new graphical console and type

cat /dev/tty0

You will see the messages that the kernel (and his modules) put into the tty0 device, the keyboard. When you are ready, close the console with a mouse click, as because of obvious reasons, you cannot abort with a keypress.

The USB layer

If you have a USB keyboard you can watch what happens on the USB bus.

  • use lsusb to find out what USB bus your keyboard is on
lsusb
  • load the kernel module usbmon
modprobe usbmon
  • analyse the respective USB bus with WireShark
wireshark

The kernel layer

If you really want to see what data comes over the wire, you have to write a kernel module, because the i386's security concept will not let anything read data but the kernel. So, create /root/keyb.c:

/*  A kernel module.
*/

#include <linux/module.h>
#include <linux/kernel.h>
#include <asm/io.h>

int init_module(void)
{
  printk("This is a kernel module\n");
  int retries = 0x100100;
  int input;
  while (--retries != 0){int oldinput=input; input=inb(0x60); if (oldinput!=input)
  printk("got %i",input);};
}

void cleanup_module(void)
{
  printk(KERN_ALERT "Au revoir\n");
}

and Makefile:

obj-m += keyb.o

and compile this:

$ make -C /lib/modules/$(uname -r)/build M=$(pwd) modules       

Now when you load this module, the kernel will, during the initialization phase (the while loop) listen to port 0x60 and print the data on wire there. So, be prepared

  • the module will take a little time to initialize
  • during the load phase, you can type a bit and you will see it in the system log
  • this is tested for the PS/2 port, but not for USB

Load the module:

insmod keyb.ko

Check the syslog:

dmesg

See also