Map an Unrecognised Key Scancode with setkeycodes
Some laptop keys, especially the extra multimedia ones, send a scancode the kernel has never heard of, and setkeycodes is how you teach it. You will identify the key, assign its scancode a kernel keycode, and verify the mapping works. The change is live in the current kernel session, not a permanent keyboard configuration, so you will also record the original mapping before changing anything.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about 10 minutes if the key is easy to isolate. You need a Linux virtual console, the kbd package, and root access for the mapping itself. A graphical terminal is not a reliable place to run showkey: use a real text console, usually reached with Ctrl+Alt+F3, and switch back with your desktop's usual console key.
1. Check the installed command
Check which program will run and which version it reports. This matters because the installed kbd 2.6.4 command accepts options the older local manual page does not list.
$ command -v setkeycodes
/usr/bin/setkeycodes
$ setkeycodes --version
setkeycodes from kbd 2.6.4
Read the command's own usage text when in doubt:
$ setkeycodes --help
Usage: setkeycodes [option...] scancode keycode ...
On this version, -C or --console=DEV selects a console device, while -h and -V print help and the version. The installed manual's OPTIONS section just says "None", so prefer the binary's own output for these version-specific flags.
2. Find the unknown scancode
Move to a virtual console before running the detector. The command waits for keyboard activity and exits after 10 seconds without a key event. Press only the unusual key you want to investigate, then let it time out.
$ showkey --scancodes
kb mode was UNICODE
press any key (program terminates 10s after last keypress)...
e0 6f
The exact output depends on the keyboard. The example shows the two-byte extended scancode e0 6f. Write it without the space as e06f when passing it to setkeycodes. No output at all means check that you are on a virtual console and that the key is not being intercepted by firmware or a desktop session first.
3. Record the current mapping
Before changing state, save the kernel's existing scancode-to-keycode table. This gives you evidence for troubleshooting and the value needed to undo the change.
$ getkeycodes | tee "$HOME/setkeycodes-before.txt"
Plain scancodes xx (hex) Keycode (dec)
00: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
...
Escaped scancodes e0 xx (hex)
e06f: 112
The table is host-specific and can be long. Find the line for the scancode you intend to alter. No existing entry is also worth recording. Do not pick a keycode already assigned to an important key unless you have a deliberate reason: keycodes are kernel-wide identifiers, not labels that belong only to your new key.
4. Choose a keycode and apply the mapping
Choose a free keycode supported by your kernel. The manual describes the historical range as 1 to 127 and notes that 2.6 kernels use 1 to 255, with 1 to 239 suggested as the safer working range. Use whatever keycode your later keymap or application expects. The example assigns the unusual key to 112, as in the manual.
Warning
This requires elevated privileges and changes live keyboard behaviour. Test from a console where you can still type a recovery command. A bad choice can make a key unusable or collide with another key.
$ sudo setkeycodes e06f 112
A successful run normally prints nothing and returns status zero:
$ printf 'exit status: %s\n' "$?"
exit status: 0
Arguments are consumed in pairs, so multiple mappings can be supplied in one command:
$ sudo setkeycodes e06f 112 e071 113
Scancodes are hexadecimal. Keycodes are decimal. Do not write 0x or use hexadecimal for the keycode unless your particular command output and kernel documentation explicitly support that.
5. Verify the resulting keycode
Run the keycode viewer and press the remapped key. It should now produce the number you selected. Release the key as well, then wait for showkey to finish.
$ showkey --keycodes
kb mode was UNICODE
press any key (program terminates 10s after last keypress)...
keycode 112 press
keycode 112 release
That confirms the kernel's keycode event. It does not define an application action: to give the key a console function, use a keymap with loadkeys. X keyboard mappings are a separate system entirely; the setkeycodes manual explicitly warns that Linux keycodes and X keycodes are not the same thing.
6. Recover from a wrong mapping
If the test is wrong, restore the original keycode from the file you saved in step 3. For example, if e06f was originally mapped to 112, use that original value again:
$ sudo setkeycodes e06f 112
If the scancode had no useful previous mapping, the safest recovery is to reboot, because this setting is held by the running kernel and is not automatically persistent. Do not guess a restore value: check the saved table or get the mapping from a known-good machine with the same keyboard and kernel setup.
Common failures, and what they mean:
- "Could not get a file descriptor referring to the console": run from a virtual console, or use the installed command's
--console=DEVoption with the correct console device. - "Not enough arguments": provide complete scancode and keycode pairs; a trailing scancode has no keycode.
- "error reading scancode": use hexadecimal characters only, such as
e06f. - The key still does nothing. Repeat discovery with
showkey --scancodes: firmware may emit a different sequence on each operating system or mode. - The command fails to remap the key. Older kernels can hardwire low scancodes, and the kernel may also reject a keycode or scancode it cannot represent.
Done means
- Scancode identified. You found it on a Linux virtual console.
- Original mapping saved. You know the recovery value.
- Mapping applied.
setkeycodesreturned status zero for the intended pair. - Result verified.
showkey --keycodesreported the chosen keycode on press and release. - Scope understood. The mapping is live-session state, and graphical key mappings need separate configuration.