Building and installing the excalibur kernel driver on immutable distributions/spins based on Fedora Silverblue
As you may know, immutable distributions are meant to keep the entire system read-only and use overlays/separate partitions to allow writing to specific user-oriented directories. Fedora achieves this on their atomic distributions by storing the entirety of overlayed directories in /var, as can be seen with Bazzite's Bash setup: yachiyo@ward-g770-baz:/var/home/yachiyo
Due to this, you cannot install external modules directly (e.g. by copying them into /usr/lib/modules/$(uname -r)/extra) and you have to package them for use with rpm-ostree instead.
The second file in this Gist is the spec file I wrote to build the Excalibur kernel driver located in thekayrasari/excalibur given you provide the source code in rpmbuild/SOURCES directory as a tarball after setting up your environment. I'll cover everything here.
To install Distrobox on distros that don't ship it:
rpm-ostree install distrobox
# And if you're lazy to reboot
sudo rpm-ostree apply-liveAnd then, to create the container:
distrobox create --name kbuild --image fedora-toolboxIf you prefer UniversalBlue's mirror instead:
distrobox create --name kbuild --image ghcr.io/ublue-os/fedora-toolboxThis will fetch the latest Fedora image if it's not present on your system already.
To enter the container you just created:
distrobox enter kbuildIn the container, run the following command to install the dependencies:
sudo dnf install -y rpm-build rpmdevtools rpmlint git make gccNo need to install kernel headers and devel package since the required content is already provided within the container under /run/host.
We first need to create and populate our rpmbuild directory. In the container, run:
rpmdev-setuptreeAfter that, we'll clone the kernel driver:
git clone https://github.com/thekayrasari/excalibur --depth=1 --no-tagsOnce that's done, we'll have to pack it up into a tarball for rpmbuild to use:
cd excalibur
git archive --format=tar.gz --prefix=excalibur-0.1/ HEAD > ~/rpmbuild/SOURCES/kmod-excalibur-0.1.tar.gzNow we're at the real deal. Building and installing it.
To build the package, head into the rpmbuild/SPECS directory and build the package:
cd ~/rpmbuild/SPECS
rpmbuild -bb kmod-excalibur.spec --define "kver $(uname -r)"If the build goes through just fine, you just have to install the produced package:
exit # Exit out of the container.
cd ~/rpmbuild/RPMS/x86_64
rpm-ostree install ./kmod-excalibur-0.1-1.fc42.x86_64.rpm # File name may vary depending on the Fedora version you build the package on.Follow this by a reboot and the package should be installed and the driver should be all set to go!
Create a script called excalibur-profile.sh in /usr/local/bin and fill it with something like the following:
#!/usr/bin/env sh
# You may optionally add brightness configuration here, but it's preserved across reboots by the driver when you set it once anyway.
echo "5bcefa" | tee /sys/class/leds/excalibur::kbd_backlight-left/color
echo "ffffff" | tee /sys/class/leds/excalibur::kbd_backlight-middle/color
echo "f5a9b8" | tee /sys/class/leds/excalibur::kbd_backlight-right/colorAfter that, create a systemd service called excalibur.service in /etc/systemd/system/. Remember, you can't write into /usr/lib without making your own package and layering it on top, so trying to write into /usr/lib/systemd/system is useless.
Put the following content in the service file:
[Unit]
Description=Excalibur laptop profile
After=multi-user.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/excalibur-profile.sh
[Install]
WantedBy=multi-user.targetOnce that's done, enable the service and run it:
sudo systemctl enable excalibur --nowAnd you're good to go!