This guide shows how to install the `gs_usb` kernel module on Linux. The steps work on both x86-64 and ARM64. > [!info] > Most Linux distributions ship with the required `gs_usb` kernel module already installed. The driver is included in Linux 3.16 and newer; CAN FD support requires Linux 5.18 or newer, or a distribution kernel with the CAN FD patches backported. # Check ```shell modinfo gs_usb ``` If this prints module information, the driver is installed and no further action is required. If it reports `Module gs_usb not found`, continue. > [!info] > If `modinfo` fails but `/sys/bus/usb/drivers/gs_usb` exists, the driver is built into the kernel and no action is required. # Install from Packages Install the package that provides kernel modules for the running kernel. | Distribution | Command | | -------------- | ------------------------------------------------------------------------- | | Debian | `sudo apt update && sudo apt install --reinstall linux-image-$(uname -r)` | | Ubuntu | `sudo apt update && sudo apt install linux-modules-extra-$(uname -r)` | | Fedora | `sudo dnf install kernel-modules-$(uname -r)` | | RHEL/CentOS 9+ | `sudo dnf install kernel-modules-$(uname -r)` | | Arch | `sudo pacman -S linux` | > [!info] > On Ubuntu, if `linux-modules-extra-$(uname -r)` is not available, use `sudo apt install linux-modules-$(uname -r)` instead. On Arch, use the package for your running kernel, for example `linux-lts`. On Arch Linux ARM, use `sudo pacman -S linux-aarch64` instead. > > If the package for the running kernel is no longer available, install the latest kernel package and reboot. Then load the module: ```shell sudo modprobe gs_usb ``` If the package is already installed and the module is still missing, the kernel was likely built without `CONFIG_CAN_GS_USB`. Continue to build from source. # Build from Source Only use this if your distribution does not provide the module. > [!info] > The kernel must have CAN and USB support enabled (`CONFIG_CAN`, `CONFIG_CAN_DEV`, and `CONFIG_USB`). ## Install Build Tools | Distribution | Command | | -------------- | ------------------------------------------------------------------------------- | | Debian/Ubuntu | `sudo apt update && sudo apt install build-essential linux-headers-$(uname -r)` | | Fedora | `sudo dnf install gcc make kernel-devel-$(uname -r)` | | RHEL/CentOS 9+ | `sudo dnf install gcc make kernel-devel-$(uname -r)` | | Arch | `sudo pacman -S base-devel linux-headers` | > [!info] > On Arch, install the headers package for your running kernel, for example `linux-lts-headers` or `linux-aarch64-headers`. ## Download the Source Download the driver source for the running kernel's base version. ```shell # Extract the base kernel version, for example 6.8.0-45-generic -> 6.8 KVER=$(uname -r | cut -d- -f1 | sed 's/[+~].*//; s/\.0$//') curl -fLO "https://raw.githubusercontent.com/torvalds/linux/v${KVER}/drivers/net/can/usb/gs_usb.c" ``` > [!tip] > If the build fails, use the kernel source package from your distribution instead of the mainline source. ## Build the Module Create a `Makefile` in the same directory. ```make obj-m += gs_usb.o ``` Build the module from the same directory. ```shell make -C /lib/modules/$(uname -r)/build M="$PWD" modules ``` ## Install the Module Install only the built module. ```shell sudo install -D -m 644 gs_usb.ko /lib/modules/$(uname -r)/extra/gs_usb.ko sudo depmod $(uname -r) ``` > [!warning] > Do not run `make modules_install`. It can overwrite modules for the running kernel. Install only `gs_usb.ko` as shown. Load the module. ```shell sudo modprobe gs_usb ``` > [!warning] > Modules built from source must be rebuilt after each kernel update. Re-run these steps for the new kernel. > [!tip] > If your distribution later provides `gs_usb`, remove the module from `/lib/modules/$(uname -r)/extra/` and run `sudo depmod $(uname -r)`. # Load at Boot On most systems, the module loads automatically when the adapter is connected. On systemd systems, to load it at boot regardless: ```shell echo gs_usb | sudo tee /etc/modules-load.d/gs_usb.conf ``` # Verify With the adapter connected: ```shell lsmod | grep gs_usb sudo dmesg | grep gs_usb ip link show ``` The adapter should appear as one `can` interface per channel, for example `can0` and `can1`. See [[Working with CAN Bus on Linux]] to configure the interface, or [[Initializing CAN interfaces with networkd]] to configure it at boot. # Troubleshooting | Symptom | Cause | Fix | | ------------------------------------------ | ------------------------------------------- | ------------------------------------------------------------------------- | | `Module gs_usb not found` | Module not installed for the running kernel | Install the package or build from source | | `Key was rejected by service` | Secure Boot is enabled | Sign the module or disable Secure Boot | | `Invalid module format` or `version magic` | Module built for a different kernel | Rebuild against `uname -r` | | No `can` interface | Adapter not connected or driver not loaded | Check `dmesg` for USB errors and confirm the adapter is listed by `lsusb` | | CAN FD does not work | Kernel lacks CAN FD support | Use Linux 5.18 or newer, or a kernel with CAN FD support | > [!warning] > If Secure Boot is enabled, unsigned modules will not load. Sign the module with a Machine Owner Key (MOK); disabling Secure Boot is not recommended. See [Kernel module signing](https://docs.kernel.org/admin-guide/module-signing.html). # References - [Linux kernel - CAN drivers](https://docs.kernel.org/networking/can.html) - [Linux kernel - gs_usb driver](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/can/usb/gs_usb.c) - [Linux kernel - Module signing](https://docs.kernel.org/admin-guide/module-signing.html)