UNPKG

arch-wiki-md-repo

Version:

All arch-wiki articles in markdown format, updated every two days.

107 lines (68 loc) 6.07 kB
This article describes how to [map scancodes to keycodes](/index.php/Map_scancodes_to_keycodes "Map scancodes to keycodes") with [udev](/index.php/Udev "Udev")'s hardware database index. Familiarity with [Keyboard input](/index.php/Keyboard_input "Keyboard input") is assumed. ## Contents * [1 Hardware database index](#Hardware_database_index) * [2 Example for custom hwdb](#Example_for_custom_hwdb) * [3 Updating the Hardware Database Index](#Updating_the_Hardware_Database_Index) * [4 Reloading the Hardware Database Index](#Reloading_the_Hardware_Database_Index) * [5 Querying the database](#Querying_the_database) ## Hardware database index [udev](/index.php/Udev "Udev") 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 `/usr/lib/udev/hwdb.d/`, `/run/udev/hwdb.d/` and `/etc/udev/hwdb.d/`. The default *scancodes-to-keycodes* mapping file is `/usr/lib/udev/hwdb.d/60-keyboard.hwdb`. See [udev(7)](https://jlk.fjfi.cvut.cz/arch/manpages/man/udev.7) for details. **Note:** From systemd 220 the udev ABI changed. Users using custom udev hwdb rules should update them according to the new ABI The *.hwdb* file can contain multiple blocks of mappings for different keyboards, or one block can be applied to multiple keyboards. The `evdev:` prefix is used to match a block against a hardware, the following hardware matches are supported: * Generic input devices (also USB keyboards) identified by the usb kernel modalias: `evdev:input:b*<bus_id>*v*<vendor_id>*p*<product_id>*e*<version_id>*-*<modalias>*` where `*<vendor_id>*`, `*<product_id>*` and `*<version_id>*` are the 4-digit hex uppercase vendor, product and version IDs (you can find those by running the `lsusb` command) and `*<modalias>*` is an arbitrary length input-modalias describing the device capabilities. `*<bus_id>*` is the 4-digit hex bus id and should be 0003 for usb devices. The possible `*<bus_id>*` values are defined in `/usr/include/linux/input.h` (you can run `awk '/BUS_/ {print $2, $3}' /usr/include/linux/input.h` to get a list). * AT keyboard DMI data matches: `evdev:atkbd:dmi:bvn*:bvr*:bd*:svn*<vendor>*:pn*<product>*:pvr*` where `*<vendor>*` and `*<product>*` are the firmware-provided strings exported by the kernel DMI modalias. * Input driver device name and DMI data match: `evdev:name:*<input device name>*:dmi:bvn*:bvr*:bd*:svn*<vendor>*:pn*` where `*<input_device_name>*` is the name device specified by the driver and `*<vendor>*` is the firmware-provided string exported by the kernel DMI modalias. You need to know the *scancodes* of keys you wish to remap. See [Keyboard input#Identifying scancodes](/index.php/Keyboard_input#Identifying_scancodes "Keyboard input") for details. 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-event-codes.h` (see the `KEY_*<KEYCODE>*` variables), a sorted list is available at [[1]](http://hal.freedesktop.org/quirk/quirk-keymap-list.txt). It is not possible to specify decimal value in `*<keycode>*`. **Tip:** You can obtain the identificator for the device you want to setup a custom *hwdb* rule for by using `# evemu-describe`. This utility provided by the [evemu](https://www.archlinux.org/packages/?name=evemu) package. ## Example for custom hwdb The example hwdb file will match all AT keyboards: `/etc/udev/hwdb.d/90-custom-keyboard.hwdb` ``` evdev:atkbd:dmi:bvn*:bvr*:bd*:svn*:pn*:pvr* KEYBOARD_KEY_10=suspend KEYBOARD_KEY_a0=search ``` Here is an example of rebinding modifiers on a laptop and USB keyboard: `/etc/udev/hwdb.d/10-my-modifiers.hwdb` ``` evdev:input:b0003v05AFp8277* # was tested on Kensington Slim Type USB (with old ABI) KEYBOARD_KEY_70039=leftalt # bind capslock to leftalt KEYBOARD_KEY_700e2=leftctrl # bind leftalt to leftctrl evdev:atkbd:dmi:* # built-in keyboard: match all AT keyboards for now KEYBOARD_KEY_3a=leftalt # bind capslock to leftalt KEYBOARD_KEY_38=leftctrl # bind leftalt to leftctrl ``` ## Updating the Hardware Database Index After changing the configuration files, the hardware database index, `hwdb.bin`, needs to be rebuilt. * Update `hwdb.bin` manually by running ``` # systemd-hwdb update ``` * Update automatically on each reboot by commenting out `ConditionNeedsUpdate` in `systemd-hwdb-update.service`. `/usr/lib/systemd/system/systemd-hwdb-update.service` ``` # This file is part of systemd. . . #ConditionNeedsUpdate=/etc . . ``` After `systemd-hwdb-update.service` finished loading `systemd-trigger.service` will reload the changes from `hwdb.bin`. * Automatically after [Systemd](/index.php/Systemd "Systemd") upgrade. On each upgrade of [Systemd](/index.php/Systemd "Systemd"), the installation script rebuilds `hwdb.bin` by running `# udevadm hwdb --update` so we do not need to care about it. ## Reloading the Hardware Database Index The kernel loads `hwdb.bin` as part of the boot process, rebooting the system will promise the loading of the updated `hwdb.bin`. With `udevadm` it is possible to load new key mapping from the updated `hwdb.bin` by running ``` # udevadm trigger ``` Be aware that with `udevadm` only added or changed key mapping are loaded so if we delete a mapping from the config file, rebuild `hwdb.bin` and run `# udevadm trigger` then the deleted mapping still kept by the kernel, at least until a reboot. ## Querying the database You can check that your configuration was loaded either by pressing keys, or by running `udevadm info`. For the USB keyboard in the above example, this outputs the mapping we configured as follows: ``` # udevadm info /dev/input/by-path/*-usb-*-kbd | grep KEYBOARD_KEY E: KEYBOARD_KEY_70039=leftalt E: KEYBOARD_KEY_700e2=leftctrl ```