Map scancodes to keycodes
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 udevudev provides a builtin function called hwdb to maintain the hardware database index in
/etc/udev/hwdb.bin. The database is compiled from files with .hwdb extension located in directories
/etc/udev/hwdb.d/. The default scancodes-to-keycodes mapping file is
man udevfor details.
The .hwdb file can contain multiple blocks of mappings for different keyboards, or one block can be applied to multiple keyboards. The
keyboard: prefix is used to match a block against a hardware, the following hardware matches are supported:
- USB keyboards identified by the usb kernel modalias:
<product_id>are the 4-digit hex uppercase vendor and product IDs (you can find those by running the
- AT keyboard DMI data matches:
<product>are the firmware-provided strings exported by the kernel DMI modalias.
- Platform driver device name and DMI data match:
<input_device_name>is the name device specified by the driver and
<vendor>is the firmware-provided string exported by the kernel DMI modalias.
The format of each line in the block body is
KEYBOARD_KEY_<scancode>=<keycode>. The value of
<scancode> is hexadecimal, but without the leading
0x (i.e. specify
a0 instead of
0xa0), whereas the value of
<keycode> is the lower-case keycode name string as listed in
/usr/include/linux/input.h (see the
KEY_<KEYCODE> variables), a sorted list is available at . It is not possible to specify decimal value in
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.
Here is an example to match all USB and AT keyboards:
keyboard:usb:v*p* keyboard:dmi:bvn*:bvr*:bd*:svn*:pn*:pvr* KEYBOARD_KEY_10=suspend KEYBOARD_KEY_a0=search
After changing the configuration files, the hardware database index needs to be rebuilt. This is done on reboot, or manually using the following command:
# udevadm hwdb --update
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.