Generate a GRUB Keyboard Layout with grub-kbdcomp

A GRUB menu that only accepts US keycodes is a nasty surprise on a UK laptop when the password or LUKS passphrase has a colon or at-sign in it. grub-kbdcomp converts an XKB layout such as us or gb into the binary .gkb format GRUB's keymap command loads. Budget about ten minutes for a straightforward layout, verification included.

You need the grub-common package and its ckbcomp dependency. This guide was checked against Ubuntu's grub-common version 2.12-1ubuntu7.3; the wrapper hands the real work to ckbcomp, so the XKB names it accepts and the errors it prints also depend on your console-setup data.

1. Check the installed tools

Run these as your normal user. Nothing here touches boot files or system configuration:

$ command -v grub-kbdcomp
/usr/bin/grub-kbdcomp
$ command -v ckbcomp
/usr/bin/ckbcomp
$ dpkg-query -W -f='${Package} ${Version}\n' grub-common
grub-common 2.12-1ubuntu7.3
$ grub-kbdcomp --help
Usage: grub-kbdcomp -o OUTPUT CKBMAP_ARGUMENTS...

Checkpoint: if either command is missing, stop and install or repair the package through your normal process. Do not copy a generated map from a different host: its layout data may not match this machine.

2. Generate a US layout in a scratch file

Write to a throwaway directory first, never straight at a live map:

$ workdir=$(mktemp -d)
$ grub-kbdcomp --output="$workdir/us.gkb" us
$ printf 'exit status: %s\n' "$?"
exit status: 0
$ ls -lh "$workdir/us.gkb"
-rw-r--r-- 1 you you 2.6K Sep 24 09:21 /tmp/tmp.example/us.gkb

Your timestamp, owner and exact size will differ; that is normal. What matters:

The output is binary, not a text keymap, so check the signature rather than eyeballing it:

$ test -s "$workdir/us.gkb" && echo "layout file is non-empty"
layout file is non-empty
$ head -c 8 "$workdir/us.gkb"
GRUBL AYO

That last command can print control characters in your terminal. For a clean read, pipe it through od instead:

$ head -c 8 "$workdir/us.gkb" | od -An -tc
   G   R   U   B   L   A   Y   O

3. Pick a different layout or variant

Anything after -o OUTPUT is a ckbcomp argument, not a grub-kbdcomp option. A British layout is just:

$ grub-kbdcomp --output="$workdir/gb.gkb" gb
$ test -s "$workdir/gb.gkb" && echo "GB layout generated"
GB layout generated

For a variant, test ckbcomp directly first; it is a useful diagnostic before you hand the same arguments to the wrapper:

$ ckbcomp -layout us -variant intl > "$workdir/us-intl.keymap"
$ test -s "$workdir/us-intl.keymap" && echo "XKB keymap generated"
XKB keymap generated
$ grub-kbdcomp --output="$workdir/us-intl.gkb" -layout us -variant intl
$ test -s "$workdir/us-intl.gkb" && echo "GRUB layout generated"
GRUB layout generated

Keep that direct ckbcomp test separate from the final .gkb file in your head: one produces a text console keymap, the other converts the same description into GRUB's binary format. If your variant is unavailable, ckbcomp reports the lookup failure; fix the spelling or check your installed XKB data, do not touch GRUB configuration to chase it.

4. Put the map where GRUB can find it

Generation itself is unprivileged. Installing into a boot or EFI filesystem is a different matter: it can need elevated privileges and it can affect the next boot. Keep the generated file until you have tested it. GRUB's manual gives keymap two ways to find a map: a bare name is looked up as layouts/NAME.gkb under GRUB's prefix, or you supply a filename directly.

Inspect the destination first. Replace the placeholder with your actual mounted GRUB directory:

$ grubdir=/path/to/grub
$ test -d "$grubdir" && echo "GRUB directory exists"
GRUB directory exists
$ install -d "$grubdir/layouts"
$ install -m 0644 "$workdir/us.gkb" "$grubdir/layouts/us.gkb"

Those install commands change system state and may need sudo if grubdir is protected. Check the result before trusting it:

$ ls -l "$grubdir/layouts/us.gkb"
-rw-r--r-- 1 root root 2.6K Sep 24 09:21 /path/to/grub/layouts/us.gkb
$ cmp "$workdir/us.gkb" "$grubdir/layouts/us.gkb" && echo "installed copy matches"
installed copy matches

Recovery: to undo this, remove only the exact installed file, after confirming no GRUB configuration still points at it. If it replaced an existing map, restore your backup instead. Never remove the whole layouts directory as a shortcut.

5. Diagnose a failed generation

A missing -o gives output file must be specified and a non-zero exit; put the output option before the layout arguments. An unknown layout gives a ckbcomp error naming the missing symbols file, which points straight at a bad or unavailable XKB name:

$ grub-kbdcomp --output="$workdir/bad.gkb" does-not-exist
/usr/bin/ckbcomp: Can not find file "symbols/does-not-exist" in any known directory
ERROR: no valid keyboard layout found. Check the input.
$ printf 'exit status: %s\n' "$?"
exit status: 1

A partial output file is not proof of success. Generate into a fresh name, check exit status and size, and only then copy it into place. If GRUB keeps using the old map, check the path, the prefix, and the argument you passed to keymap. This tool only ever generates the layout file: it does not edit grub.cfg, install GRUB, or change the keyboard Linux uses after boot.

Done means