First find the scancode of the key that needs to be remapped, e.g. with the `evtest` utility. A line like the following one (with `MSC_SCAN` in it) should be output:

 Event: time 1417131619.686259, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70068

followed by a second one giving the current key code. If no `MSC_SCAN` line is output, this is due to a kernel driver bug, but the scancode can still be found with the `input-kbd` utility; `evtest` should have given the key code, so that it should be easy to find the corresponding line in the `input-kbd` output (e.g. by using `grep`).

Once the scancodes of the keys to be remapped have been determined, create a file such as `/etc/udev/hwdb.d/98-custom-keyboard.hwdb` containing the remappings. The beginning of the file `/lib/udev/hwdb.d/60-keyboard.hwdb` gives some information. In my case (which works), I have:

 evdev:input:b0003v05ACp0221*
 KEYBOARD_KEY_70035=102nd # Left to z: backslash bar
 KEYBOARD_KEY_70064=grave # Left to 1: grave notsign
 KEYBOARD_KEY_70068=insert # F13: Insert

(Before udev 220, I had to use `keyboard:usb:v05ACp0221*` for the first line.)

The `evdev:` string must be at the beginning of the line.
Note that the letters in the vendor and product id should be capital letters.
Each `KEYBOARD_KEY_` settings should have exactly one space before (note: a line with no spaces will give an error message, and a line with two spaces were *silently* ignored with old udev versions). `KEYBOARD_KEY_` is followed by the scancode in hexadecimal (like what both `evtest` and `input-kbd` give). Valid values could be obtained from either the `evtest` output or the `input-kbd` output, or even from the `/usr/include/linux/input.h` file: for instance, `KEY_102ND` would give `102nd` (by removing `KEY_` and converting to lower case), which I used above.

After the file is saved, type:

 udevadm hwdb --update

to (re)build the database `/etc/udev/hwdb.bin` (you can check its timestamp). Then,

 udevadm trigger --sysname-match="event*"

will take the new settings into account. You can check with `evtest`.

In 2014, the released udev had incomplete/buggy information in `/lib/udev/hwdb.d/60-keyboard.hwdb`, but you can look at [the latest development version of the file](http://cgit.freedesktop.org/systemd/systemd/tree/hwdb/60-keyboard.hwdb) and/or [my bug report and discussion](https://bugs.freedesktop.org/show_bug.cgi?id=82311) concerning the documentation and spacing issues.

If this doesn't work, the problem might be found after temporarily increasing the log level of `udevd` with `udevadm control` (see the udevadm(8) man page for details).

For old `udev` versions such as 204, [this method](https://www.vinc17.net/unix/xkb.en.html#udev) should still work.