Posted on

2 random truths about me:

  1. I tend to wake up quite early: I am an early bird
  2. While I (mostly) prefer light mode on the computer I prefer dark mode in real life

What does this have to do with mkinitcpio?

I wake up, there is no sunlight, I do not switch on any lights. I turn on my laptop and my hard disk encryption is greeting me. The problem is the keyboard is completely dark and I tend to hit the wrong keys.

Now I finally fixed it.

As I am using Arch Linux (btw. I use Arch) the thing that is greeting me in the mornings is the initramfs of arch linux with the encryption module. While I do have proper keyboard backlight support with my Laptop (an ASUS G14) the initramfs that Arch has been generating didn't have it. So I finally dug into it and fixed it.

The process is very well documented in the arch wiki:

https://wiki.archlinux.org/title/Mkinitcpio

Long story short I implemented a build hook (which is executed when you execute mkinitcpio -P to generate your initramfs) and saved it as /etc/initcpio/install/kbd_backlight:

#!/bin/bash

build() {
    add_module hid_asus
    add_runscript
}

help() {
    cat <<HELPEOF
Force kbd light
HELPEOF
}

# vim: set ft=sh ts=4 sw=4 et:

A build script needs to implement two functions: build and help.

The build step adds the hid_asus module (and all of its dependencies!) to the initial ramdisk. It also adds the following runscript (which needs to be located at /etc/initcpio/hooks/kbd_backlight where kbd_backlight is the same name like the build hook) to it:

#!/usr/bin/ash

run_hook() {
    modprobe hid_asus
    i=0
    while [[ ! -f "/sys/class/leds/asus::kbd_backlight/brightness" ]]; do
        if [[ "$i" -eq 3 ]]; then
            echo "ERR> asus keyboard module not found"
            exit 1
        fi
        sleep 1
	    i=$((i+1))
    done
    echo 1 > /sys/class/leds/asus::kbd_backlight/brightness
}

# vim: set ft=sh ts=4 sw=4 et:

Note that it uses a different shell. bash is NOT included in the initramfs by default!

Now this simple script loads the hid_asus module (which the build script added to the initramfs) which allows keyboard backlight manipulation. Note that after loading the kernel module the module starts its work asynchronously which is why we need a small while loop to wait for initialization.

Once the module is initialialized we can just set the keyboard backlight to 1 and we can finally see the keys before decrypting the harddisk đź’«

To enable a custom hook in mkinitcpio just add it to the list of modules in /etc/mkinitcpio.conf. Mine is looking like this now:

[...]
HOOKS=(base udev autodetect modconf block kbd_backlight encrypt filesystems keyboard fsck)
[...]

Note that order matters. So it must be placed before the encrypt hook!