Compiling and Loading an Out-of-Tree Kernel Driver on Jetson
- Author:
Eduardo Hernández Valdez
Introduction
Jetson’s L4T (Linux for Tegra) ships with a fixed set of kernel modules. If your hardware requires a driver not included (such as a USB CAN adapter using gs_usb), you need to compile it yourself from the matching kernel source and load it manually. This guide walks through that process end to end.
The gs_usb driver is used as a running example. If you are targeting a different driver, substitute the relevant CONFIG_ key, source path, and .ko filename where appropriate.
1 - Verify your L4T Version
Confirm the exact L4T release running on your Jetson:
cat /etc/nv_tegra_release
Expected output:
# R36 (release), REVISION: 4.3, GCID: 38968081, BOARD: generic, EABI: aarch64, DATE: Wed Jan 8 01:49:37 UTC 2025
# KERNEL_VARIANT: oot
TARGET_USERSPACE_LIB_DIR=nvidia
TARGET_USERSPACE_LIB_DIR_PATH=usr/lib/aarch64-linux-gnu/nvidia
Note the release (R36) and revision (4.3). You need these to download the correct kernel sources.
2 - Install Build Dependencies
sudo apt-get install build-essential bc kmod libssl-dev
3 - Download the Kernel Sources
Navigate to the Jetson Linux archive and find the entry matching your L4T version:
https://developer.nvidia.com/embedded/jetson-linux-archive
Download the Driver Package (BSP) Sources (public_sources.tbz2) for your exact release.
4 - Extract the Sources
Place the downloaded archive in a working folder, then extract:
tar -xjf public_sources.tbz2
cd Linux_for_Tegra/source
tar -xjf kernel_src.tbz2
cd kernel
cd kernel-jammy-src
Note
The inner folder name (e.g. kernel-jammy-src) may differ depending on your Ubuntu and L4T version. Enter whichever single folder is present at that level.
5 - Copy Your Current Kernel Configuration
Use the running kernel’s configuration as the build base so your compiled module is compatible:
zcat /proc/config.gz > .config
6 - Enable the Driver in .config
Open .config with your preferred text editor and search for the driver’s config key. For gs_usb it looks like:
# CONFIG_CAN_GS_USB is not set
Change the line to:
CONFIG_CAN_GS_USB=m
The =m value tells the build system to compile it as a loadable module instead of building it into the kernel image. Save and close the file.
7 - Prepare the Build Environment
make ARCH=arm64 LOCALVERSION=-tegra olddefconfig
make ARCH=arm64 LOCALVERSION=-tegra modules_prepare
8 - Compile the Driver
make ARCH=arm64 LOCALVERSION=-tegra M=drivers/net/can/usb modules
Note
The M= path points to the folder containing the driver’s source. To find the right folder for a different driver:
find . -name "*.c" | xargs grep -rl "MODULE_ALIAS\|module_init" | grep -i <driver_name>
Set M= to the containing directory of the result.
9 - Install the Module
Create the destination directory mirroring the kernel’s module tree:
sudo mkdir -p /lib/modules/$(uname -r)/kernel/drivers/net/can/usb/
Copy the compiled module:
sudo cp drivers/net/can/usb/gs_usb.ko /lib/modules/$(uname -r)/kernel/drivers/net/can/usb/
Update the module dependency database:
sudo depmod -a
10 - Load the Driver
sudo modprobe gs_usb
Verify it loaded:
lsmod | grep gs_usb
If no errors appear and the module shows up in lsmod, your driver is active. Happy linuxing!
Note
To load the module automatically at boot, add its name to /etc/modules:
echo "gs_usb" | sudo tee -a /etc/modules
Troubleshooting
- “No rule to make target” or module not found after
make modules Confirm
CONFIG_CAN_GS_USB=mis present in.configand that you ran botholddefconfigandmodules_preparebefore the module compile step.- Kernel version mismatch: module refuses to load
The compiled
.komust match the running kernel exactly. Check:uname -r modinfo drivers/net/can/usb/gs_usb.ko | grep vermagic
Both strings must match. If they differ, you downloaded sources for the wrong L4T revision. Re-download the correct one.
- “Required key not available” on
modprobe Kernel has module signature enforcement enabled. Either disable it (not recommended on production systems) or sign the module with the kernel’s signing key. Refer to Nvidia’s BSP documentation for the key location.
- ``depmod`` reports missing symbols
The module depends on another module that is not loaded or not present. Check dependencies:
modinfo gs_usb.ko | grep depends
Ensure all listed modules are available under
/lib/modules/$(uname -r)/.- Device not recognized after
modprobe Confirm hardware is connected, then inspect kernel messages for binding errors:
dmesg | tail -30