How I got a Kamvas 13 Gen 3 working properly on Linux
Recently I’ve come into contact with one of the recent Huion pen displays; this turned into an unexpected deep dive inside the HID BPF subsystem, which is awesome if you think about it.
The pen display itself
The pen display itself has some pretty good specifications for what it offers: 1080p 13” screen, factory calibrated to give off 99% of sRGB coverage; a stylus with three buttons and tilt/pressure support; two rotary dials and seven buttons on the tablet. It can be used stand-alone via USB-C or it can also be paired to an octopus-like cable that splits a proprietary connection that also uses USB-C as a connector only to provide HDMI, USB-A for tablet input and another USB-A for powering the whole thing off a charging brick.
It supports two modes: a “vendor mode” and a “firmware mode”.
The “vendor mode” is what the tablet uses when it’s paired with the official Huion driver, on Windows, MacOS and Ubuntu. It will pass its data onto the userspace driver that, in turn, makes sense of it and makes stuff happen like the user wants it (ie. button mapping, stylus area mapping, etc.)
The “firmware mode” is used if using the pen display with Android or other Linux distros: it will send the stylus events unmapped, whereas the tablet dials and keys are mapped to some standard shortcuts that most people would expect. The catch here is that you cannot remap or adjust anything, but it is “better than nothing” for most people drawing on, say, Android tablets.
The Huion Tablet Driver on Linux
Huion does support Ubuntu 20.04 LTS only, at the moment, but community ports of the official drivers are also available on AUR for Arch-based distros. Needless to say, their driver package is specifically made with Ubuntu and X11 in mind, so it won’t work as intended outside of those two constraints.
This means that, since I am currently using Artix Linux with KDE Plasma on a Wayland session, I embody the total opposite of what the Huion development team envisioned as a “Linux user”. So, what next? Enter eBPF.
So, what is eBPF?
eBPF is a technology that can run programs in a privileged context such as the operating system kernel. […] It is used to safely and efficiently extend the capabilities of the kernel at runtime without requiring changes to kernel source code or loading kernel modules. Safety is provided through an in-kernel verifier which performs static code analysis and rejects programs which crash, hang or otherwise interfere with the kernel negatively.
Source: Wikipedia Article
So effectively we can leverage small programs to extend the functionality of the kernel without writing entire kernel modules for it. Neat!
eBPF is used in the Linux kernel for network filtering, extending schedulers, and also extending the HID subsystem (our intended goal, HID-BPF).
This applies to our use-case because we have a pen display which needs a driver for it, but we don’t
want to write an entire driver for it (because it’d technically be hid-uclogic but for some reason
they’re not adding support for most new tablets there anymore? I don’t know.)
Setting it up
To set up HID-BPF for my pen display I needed:
- A BPF program;
- A loader that loads the program into the kernel for the input device I have.
According to the HID-BPF documentation there’s only one
loader for this kind of stuff, and that is
udev-hid-bpf. I know that this
project will scare most of my readers away, since it’s made in Rust, it’s under the FDO umbrella and
it depends on udev, which is a systemd component - but it is what it is, and chances are you can
give all of this a pass if you really really need some kind of quirky input device to function.
Let’s proceed, then.
HID-BPF conveniently also bundles some BPF programs that will aid with some devices, and the pen display I am using is also conveniently included.
Following their guide on how to get it pre-compiled from the CI, which I dearly recommend anyway, I downloaded the latest build. I know that the guide confuses people easily, so let’s just make a smaller and more concise one:
- Go here;
- Eyeball the first result and look at the right side on the download dropdown, click it;
- You’re looking for the “make release:archive” artifact. Click on that;
- Unzip the resulting zipfile wherever.
Now, provided you have sudo or doas and a sudo symlink to doas if you are fancy, you can run
the install.sh file that is inside that archive. And yes, for some reason sudo is required.
./install.sh --interactive
Do keep in mind that the command above can install HID-BPF programs to support other devices beside the Kamvas 13 (and 16) Gen 3. Check the complete list of programs here.
Now, at the end, if you’re not running a distribution that runs Systemd you might’ve had the setup
script error out because systemd-hwdb is not found. In most cases you can just issue the following
command instead:
sudo udevadm hwdb --update
sudo udevadm control --reload
It will complain that hwdb is deprecated but since you don’t have systemd-hwdb and you will
probably never have that, it’s fine anyway.
If you’re using this post as a tutorial, please unplug and replug your pen display now.
But why not installing all of this from your distro’s package manager? Well, Arch/Endeavor/Cachy/etc. will have the loader readily packaged for you (on the Arch vanilla repos), but without any HID-BPF programs bundled with it. I don’t know about Debian/Fedora/other distros though, so if you want an easier life please check the availability for your distro.
At this point I had a pen display that would work, with its inputs being intercepted and passed to the userspace in a way that lets me map them to other convenient stuff. This is probably where most people (with up to date packages) will end their journey, however, for the sake of completeness, I will push on forwards because I had some other problems by this point.
libwacom still needs to be updated
Libwacom is a library that contains data which describes all sorts of pen tablets and pen displays to the Linux userspace. It is crucial to us because if we want to get our tablet recognized by our DE’s system settings, it most probably needs to be recognized by this library itself.
Libwacom has a commit upstream that will render this rant basically useless, but since at the time of writing their last released version is 2.17.0, and I don’t see any 2.18.0 coming out anytime soon, I needed to replicate this commit to my data:
sudo nano /usr/share/libwacom/huion-kamvas-13-gs1333.tablet
Again, check your version of Libwacom, because you’re reading this article from a point in time called “the future”, and your computer might already have this fix applied.
If you’re also following this section as a tutorial because your distro might have an older version of Libwacom, please unplug and replug your pen display now. It should now be recognized and usable across the system.
Vendor mode anyone?
Still unsatisfied, I wanted my tablet to be used to its fullest potential: I wanted it to work using the vendor mode, as it’s the most accurate mode for the tablet, and the translation will be more effective that way.
To switch Huion devices into their respective vendor mode, there’s a tool called huion-switcher.
This is also made in Rust, sorry.
Anyway, download said tool from the releases
section on the GitHub repo, or compile it yourself if you love Cargo that much. In any case, you
have to copy the binary where udev can recognize and execute it:
sudo cp huion-switcher /usr/lib/udev/
Then, you have to also copy some udev rules so that effectively it will get called:
sudo cp 80-huion-switcher.rules /etc/udev/rules.d/
sudo udevadm control --reload
Again, if you’re using this post as a tutorial, please unplug and replug the tablet now: it should work as before, but now it’ll be using the vendor mode.
Seeing if eBPF programs are loaded
I am leaving this here because this can be useful to some:
sudo tree /sys/fs/bpf
This command will list every eBPF program that is loaded in the kernel, and for which device it is loaded, too.
Conclusion
eBPF is a neat thing and it’s sad that eBPF programs aren’t just compiled, shipped and loaded fully within the kernel as a more official “band-aid solution”, at least for the ever-evolving landscape of HID devices.
I hope that this post made you learn something new about Linux, whether you use a Linux-based operating system already or you’re considering switching to Linux and have (or planning to buy) a Huion (or similar brand) pen display (or tablet.)
Addendum: Happy festivities, everyone!
I’d be brief: this year was hell for me personally.
I had to deal with some stuff which would be too bad to talk about because it would question the
status quo for some people, so to put it lightly: protect your loved ones. People like me are
vulnerable, but sadly the “health bill” will be handed to us sooner or later and it’ll be our call
to be responsible. For me personally, the people who should’ve “supported me the most” did then disappear
into thin air — everything is just politics, isn’t it? Don’t be fooled, be responsible and take
action over your decisions only.
Oh, if only I had done this many years ago, I would probably have been happier and way, way less
miserable.
So, what will it be for the next year? I have some proposals for myself:
- Write more posts/tutorials around Linux and more;
- Be healthy, be fit, lose weight, seek self-improvement in psyche and body;
- Finish my studies, and actually I am getting closer to that finish line;
- Actually get a job, at least on the side;
- “Undo” most of the cringey shit I no longer associate myself with, per previous paragraph;
- Be positive, spread critical awareness through and through.
So, what’ll your call be? Did you make a list of to-do’s for the next year? Whether you love or hate me, or you know me or not, or you have something in common with my own to-do list or not, I will be here wishing the best for you too.
Sincerely,
Your Dear Nao