Skip to content

Instantly share code, notes, and snippets.

@fkjbvfdvbnfdkjvbjfhd
Last active August 25, 2026 15:23
Show Gist options
  • Select an option

  • Save fkjbvfdvbnfdkjvbjfhd/e0a5da0c012e10d715b0b7df3a3d3632 to your computer and use it in GitHub Desktop.

Select an option

Save fkjbvfdvbnfdkjvbjfhd/e0a5da0c012e10d715b0b7df3a3d3632 to your computer and use it in GitHub Desktop.
Building and installing the excalibur kernel driver on immutable distributions/spins based on Fedora Silverblue

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.

Using Distrobox to create a build container

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-live

And then, to create the container:

distrobox create --name kbuild --image fedora-toolbox

If you prefer UniversalBlue's mirror instead:

distrobox create --name kbuild --image ghcr.io/ublue-os/fedora-toolbox

This will fetch the latest Fedora image if it's not present on your system already.

To enter the container you just created:

distrobox enter kbuild

Installing build dependencies

In the container, run the following command to install the dependencies:

sudo dnf install -y rpm-build rpmdevtools rpmlint git make gcc

No need to install kernel headers and devel package since the required content is already provided within the container under /run/host.

Preparing the build environment

We first need to create and populate our rpmbuild directory. In the container, run:

rpmdev-setuptree

After that, we'll clone the kernel driver:

git clone https://github.com/thekayrasari/excalibur --depth=1 --no-tags

Once 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.gz

Building and installing the package

Now 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!

Extra: The systemd service to set a specific keyboard backlight on boot

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/color

After 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.target

Once that's done, enable the service and run it:

sudo systemctl enable excalibur --now

And you're good to go!

%global debug_package %{nil}
Name: kmod-excalibur
Version: 0.1
Release: 3%{?dist}
Summary: Excalibur WMI kernel module
License: MIT
URL: https://github.com/thekayrasari/excalibur
Source0: %{name}-%{version}.tar.gz
BuildRequires: gcc
BuildRequires: make
ExclusiveArch: x86_64
%description
Out-of-tree WMI kernel module for Excalibur laptops.
%prep
%autosetup -n excalibur-%{version}
%build
make -C /run/host/usr/src/kernels/%{kver} M=$PWD modules
%install
mkdir -p %{buildroot}/usr/lib/modules/%{kver}/extra
install -Dm0644 excalibur.ko %{buildroot}/usr/lib/modules/%{kver}/extra/excalibur.ko
mkdir -p %{buildroot}/usr/lib/modules-load.d
echo excalibur > %{buildroot}/usr/lib/modules-load.d/excalibur.conf
install -Dm644 control-panel.py %{buildroot}/usr/lib/excalibur-control-panel.py
mkdir -p %{buildroot}/usr/bin
cat > %{buildroot}/usr/bin/excalibur-panel <<LAUNCHER
#!/bin/bash
# Excalibur Control Panel launcher
exec python3 /usr/lib/excalibur-control-panel.py
LAUNCHER
chmod 755 %{buildroot}/usr/bin/excalibur-panel
mkdir -p %{buildroot}/usr/lib/udev/rules.d
cat > %{buildroot}/usr/lib/udev/rules.d/99-excalibur.rules <<UDEV
# excalibur-wmi udev rules
# Grants write access to LED zones and power plan for wheel/sudo group members,
# allowing the control panel to run without sudo.
# Keyboard LED zones
SUBSYSTEM=="leds", KERNEL=="excalibur*", \
RUN+="/bin/sh -c 'chown root:wheel /sys%p/brightness /sys%p/color /sys%p/mode /sys%p/raw 2>/dev/null; chmod g+w /sys%p/brightness /sys%p/color /sys%p/mode /sys%p/raw 2>/dev/null'", \
RUN+="/bin/sh -c 'chown root:sudo /sys%p/brightness /sys%p/color /sys%p/mode /sys%p/raw 2>/dev/null; chmod g+w /sys%p/brightness /sys%p/color /sys%p/mode /sys%p/raw 2>/dev/null'"
# hwmon (fan speeds + power plan)
SUBSYSTEM=="hwmon", ATTR{name}=="excalibur_wmi", \
RUN+="/bin/sh -c 'chown root:wheel /sys%p/pwm1 /sys%p/fan1_input /sys%p/fan2_input 2>/dev/null; chmod g+rw /sys%p/pwm1 2>/dev/null'", \
RUN+="/bin/sh -c 'chown root:sudo /sys%p/pwm1 /sys%p/fan1_input /sys%p/fan2_input 2>/dev/null; chmod g+rw /sys%p/pwm1 2>/dev/null'"
UDEV
mkdir -p %{buildroot}/usr/share/applications
cat > %{buildroot}/usr/share/applications/excalibur-panel.desktop <<DESKTOP
[Desktop Entry]
Version=1.0
Type=Application
Name=Excalibur Control Panel
GenericName=Laptop Control Panel
Comment=RGB lighting, fan monitoring and power plan control for Excalibur laptops
Exec=bash -c 'exec python3 /usr/lib/excalibur-control-panel.py'
Icon=input-keyboard
Terminal=true
Categories=System;HardwareSettings;
Keywords=excalibur;rgb;keyboard;fan;laptop;
StartupNotify=false
DESKTOP
%post
/sbin/depmod -a %{kver} || :
%postun
/sbin/depmod -a %{kver} || :
%files
/usr/lib/modules/%{kver}/extra/excalibur.ko
/usr/lib/modules-load.d/excalibur.conf
/usr/lib/excalibur-control-panel.py
/usr/bin/excalibur-panel
/usr/lib/udev/rules.d/99-excalibur.rules
/usr/share/applications/excalibur-panel.desktop
%changelog
* Tue Mar 31 2026 Bahar KURT <kurtbahartr@gmail.com> - 0.1-3
- Version bump upon kernel update by Bazzite: 6.17.7-ba28.fc43.x86_64 -> 6.17.7-ba29.fc43.x86_64
* Thu Mar 26 2026 Bahar KURT <kurtbahartr@gmail.com> - 0.1-2
- Sync with the latest changes
- Add support for Excalibur Control Panel (including the udev rule)
* Sun Mar 15 2026 Bahar KURT <kurtbahartr@gmail.com> - 0.1-1
- Initial package
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment