Map scancodes to keycodes

From ArchWiki
Revision as of 18:26, 21 September 2013 by Bugmenot2 (talk | contribs) (update for newer versions of systemd/udev >=206. This still needs work, maybe there are easier/faster ways. Based on and an IRC chat.)
Jump to: navigation, search

Scancodes are the lowest identification numbers for a key, it is the value that a keyboard sends to a computer. Scancodes are mapped to keycodes, which are then mapped to keysyms depending on used keyboard layout. Mapping scancodes to keycodes is universal and not specific to Linux console or Xorg, which means that changes to this mapping will be effective in both.

See Extra Keyboard Keys for more information.

There are two ways of mapping scancodes to keycodes:

  • Using udev
  • Using setkeycodes

The preferred method is to use udev because it uses hardware information (which is a quite reliable source) to choose the keyboard model in a database. It means that if your keyboard model has been found in the database, your keys are recognized out of the box.

Using udev

Tango-view-refresh-red.pngThis article or section is out of date.Tango-view-refresh-red.png

Reason: Needs to be compatible with the new changes introduced in systemd 206. The old tools have been replaced by hwdb and the "keyboard" udev builtin. (Discuss in Talk:Map scancodes to keycodes#)

You need to create a keymap file that udev will recognize. The default list with many examples can be found in /usr/lib/udev/hwdb.d/60-keyboard.hwdb.

Create a .hwdb (extension is important) file in /etc/udev/hwdb.d/. The format of each line for a keymap is KEYBOARD_KEY_<scancode>=<keycode>. You can work out <scancode> (looks like XX) pressing the desired key, and looking the output of dmesg | tail. For example, if you get: Unknown key pressed (translated set 2, code 0xa0 on isa0060/serio0 the <scancode> you need is a0, not the full 0xa0.

The choices for <keycode> are listed as KEY_<KEYCODE> in /usr/include/linux/input.h, but you need to change these to lower case and remove the KEY_ prefix (for example, KEY_PROG3 corresponds to prog3). A sorted list is available here.

USB keyboards are identified by the usb kernel modalias: keyboard:usb:vXXXXpYYYY* where XXXX is the 4-digit hex uppercase vendor, and YYYY the 4-digit hex uppercase product. While AT keyboard DMI data matches are: keyboard:dmi:bvn*:bvr*:bd*:svn<vendor>:pn<product>:pvr* where <vendor> and <product> are the firmware-provided strings exported by the kernel DMI modalias.

An example to match all DMI keyboards:


Now the keymap will be active the next time you restart. You can run the following command as root to activate it immediately:

# udevadm hwdb --update

For more information about keymaps, see man udev.

Using setkeycodes

setkeycodes is a tool to load scancodes-to-keycodes mapping table into Linux kernel. Its usage is:

# setkeycodes scancode keycode ...

It is possible to specify multiple pairs at once. Scancodes are given in hexadecimal, keycodes in decimal.