USRP Hardware Driver and Device Manual  Version: 4.11.0.0-0-g0d7ed3b1
UHD and USRP Manual
B3xx Kernel Module Installation and Usage

Installing the Linux Kernel Module

Overview

The B310 PCIe transport on Linux requires the nib310rio kernel module. Without this module, UHD cannot discover or use the B310 device over the PCIe or Thunderbolt interface.

Requirements

  • Linux kernel headers for the running kernel
  • Build tools (gcc, make)
  • dkms (recommended for package-based installs)

Example (Ubuntu/Debian):

sudo apt update
sudo apt install -y dkms gcc make linux-headers-$(uname -r)

Linux Desktop Installation

For standard Linux desktop systems (for example Ubuntu or Fedora), install the nib310rio driver packages and ensure the module is loaded.

Download the latest Linux kernel driver packages from Ettus UHD latest release binaries.

The package names and roles are:

  • nib310rio-dkms: Required runtime kernel driver package. This package builds and installs the nib310rio kernel module via DKMS.
  • nib310rio-dev: Development header package. This installs /usr/include/nib310rio/nib310rio.h, which is required to compile B310 support in UHD.

Example install flow (Debian/Ubuntu):

sudo dpkg -i nib310rio-dkms_<version>_all.deb
sudo dpkg -i nib310rio-dev_<version>_all.deb

For Fedora/RHEL-like systems, install the equivalent RPM packages:

sudo dnf install ./nib310rio-dkms-<version>-1.noarch.rpm
sudo dnf install ./nib310rio-dev-<version>-1.noarch.rpm

After installation, validate that the module is present:

lsmod | grep nib310rio

If needed, load it manually:

sudo modprobe nib310rio

Then verify that UHD can discover the device:

uhd_find_devices --args type=b3xx

Linux Package Troubleshooting

The checks below summarize common package-installation failures and validation steps observed in the B310 Linux driver package installation flow.

Dependency issues

If dkms install reports missing pahole:

sudo apt install -y pahole
sudo apt install -y dkms

If dpkg -i leaves nib310rio-dkms unconfigured due to unmet dependencies:

sudo apt --fix-broken install -y
sudo dpkg --configure -a

Validate DKMS and module placement

After package installation, validate DKMS state and module location:

dkms status | grep nib310rio
modinfo -n nib310rio

Expected:

  • dkms status reports nib310rio installed for the running kernel.
  • modinfo -n nib310rio resolves to a path under /lib/modules/....

Sample package installation output

The following abbreviated output snippets are examples of successful package installation.

Debian/Ubuntu (nib310rio-dkms):

$ sudo dpkg -i nib310rio-dkms_<version>_all.deb
Setting up nib310rio-dkms (<version>) ...
Building module:
...
nib310rio.ko:
...
Installing to /lib/modules/<kernel>/updates/dkms/
depmod...

Fedora/RHEL (nib310rio-dkms):

$ sudo dnf install ./nib310rio-dkms-<version>-1.noarch.rpm
Installing:
nib310rio-dkms-<version>-1.noarch
...
Building module(s)... done.
Installing /lib/modules/<kernel>/.../nib310rio.ko.xz
Running depmod... done.
Complete!

Secure Boot considerations

On Secure Boot systems, module build/install may succeed but modprobe can fail with key rejection until a trusted key is enrolled and the module is rebuilt and re-signed. If this occurs, follow your distribution's MOK enrollment flow, then rebuild/reinstall the DKMS module.

Typical error:

modprobe: ERROR: could not insert 'nib310rio': Key was rejected by service

On Debian/Ubuntu systems, the flow is typically:

  1. Install MOK tooling:
     sudo apt install -y shim-signed mokutil
    
  2. Reboot and enroll the key in MOK Manager:
    • Select Enroll MOK.
    • Select Continue.
    • Select Yes.
    • Enter the enrollment password set during shim-signed installation.
    • Select Reboot.
  3. Rebuild and reinstall the DKMS module after enrollment:
     sudo dkms remove nib310rio/<version> --all || true
     sudo dkms add -m nib310rio -v <version>
     sudo dkms build -m nib310rio -v <version> -k "$(uname -r)"
     sudo dkms install -m nib310rio -v <version> -k "$(uname -r)" --force
     sudo depmod -a
     sudo modprobe nib310rio
    
  4. Verify Secure Boot state, module signer, and module load:
     mokutil --sb-state
     modinfo nib310rio | grep -i signer
     lsmod | grep nib310rio
    

Validate installed artifacts

Confirm that expected packaging artifacts are present:

test -f /etc/udev/rules.d/99-nib310rio.rules && echo "udev rule present"
test -f /etc/modules-load.d/nib310rio.conf && echo "autoload config present"
test -f /usr/include/nib310rio/nib310rio.h && echo "dev header present"

Jetson AGX Orin

This section targets Jetson Linux 39.2.1 / JetPack 7.2.1 (Ubuntu 24.04, kernel 6.8). The commands use its native source layout, where the kernel tree is kernel/kernel-noble/.

On Jetson AGX Orin, the B310 software path requires Linux DMA-BUF heap support. In particular, /dev/dma_heap/system must be available. If this device node is missing, DMA-based operation will fail and only limited BAR0 access may work.

Recommended Jetson workflow

Use the following sequence when enabling B310 support on Jetson:

  1. Enable DMA-BUF feature support (if missing) and verify /dev/dma_heap/system.
  2. Install the nib310rio kernel driver packages as in the Linux desktop case (see Linux Desktop Installation).
  3. Build and test UHD on Jetson.

Verify Jetson software version

Confirm the target release on the Jetson host:

uname -r
cat /etc/nv_tegra_release

Enable DMA-BUF heap support

NVIDIA kernel customization reference: Jetson Linux Kernel Customization

The procedure below builds the kernel natively on the Jetson and installs it on that same device. A cross-compiled kernel must instead be installed through the Jetson Linux Linux_for_Tegra flashing workflow; do not run the /boot copy or modules_install commands below on the cross-build host.

Build environment setup:

sudo apt update
sudo apt install -y git build-essential bc flex bison libssl-dev zstd

Download and extract the Jetson Linux release package and public sources for the target release from the Jetson Linux archive. The release must match the version reported by cat /etc/nv_tegra_release. In the commands below, <install-path> is a directory on the Jetson, for example ~/jetson_linux, and <public-sources-path> is the path to the downloaded archive, for example ~/Downloads/public_sources.tbz2.

For Jetson Linux 39.2.1, download Driver Package (BSP) Sources (public_sources.tbz2).

Extract the public sources, then extract the matching source archives from its Linux_for_Tegra/source/ directory:

tar xf <public-sources-path> -C <install-path>
cd <install-path>/Linux_for_Tegra/source
tar xf kernel_src.tbz2
tar xf kernel_oot_modules_src.tbz2
tar xf nvidia_kernel_display_driver_source.tbz2

This release package does not include source_sync.sh; use the public-source archives instead. Seed the new kernel configuration from the running kernel:

zcat /proc/config.gz > kernel/kernel-noble/.config
cd kernel/kernel-noble
export ARCH=arm64
export LOCALVERSION=-tegra
make olddefconfig

Enable these options as built-ins (=y):

CONFIG_DMA_SHARED_BUFFER=y
CONFIG_DMABUF_HEAPS=y
CONFIG_DMABUF_HEAPS_SYSTEM=y
CONFIG_SYNC_FILE=y

Apply the configuration and resolve its dependencies:

scripts/config --enable DMA_SHARED_BUFFER
scripts/config --enable DMABUF_HEAPS
scripts/config --enable DMABUF_HEAPS_SYSTEM
scripts/config --enable SYNC_FILE
make olddefconfig

Build the kernel and its in-tree modules. The resulting release string is 6.8.12-tegra, so installing the matching modules is required even when the running stock kernel is 6.8.12-1021-tegra:

make -j$(nproc) Image
make -j$(nproc) modules
sudo -E make modules_install

Build and install the NVIDIA out-of-tree modules against the same kernel tree:

cd <install-path>/Linux_for_Tegra/source
export ARCH=arm64
export LOCALVERSION=-tegra
export KERNEL_HEADERS=$PWD/kernel/kernel-noble
export kernel_name=noble
make -j$(nproc) modules
sudo -E make modules_install

Stage the new image under a separate name, leaving the original boot image unchanged:

sudo cp <install-path>/Linux_for_Tegra/source/kernel/kernel-noble/arch/arm64/boot/Image \
    /boot/Image.dmabuf

No devicetree changes are required for DMA-BUF heaps, so the installed DTBs can be reused.

Add a dmabuf entry to /boot/extlinux/extlinux.conf. Its APPEND value is system-specific; copy it from the existing primary entry:

LABEL dmabuf
MENU LABEL dmabuf-heaps kernel (6.8.12-tegra)
LINUX /boot/Image.dmabuf
INITRD /boot/initrd
APPEND <copy the APPEND value from the primary entry>

Leave DEFAULT set to primary. Reboot the Jetson, then select dmabuf from the boot menu to test the new kernel. After verification, it can instead be made the default by setting DEFAULT dmabuf. If the test kernel does not boot or essential peripherals fail, select primary to return to the original image.

Verify DMA-BUF after reboot

After booting the dmabuf entry, confirm the new kernel is active:

uname -r

Expected: 6.8.12-tegra.

Check kernel config:

zgrep DMABUF /proc/config.gz

Verify DMA heap node exists:

ls -l /dev/dma_heap/

Expected: system entry under /dev/dma_heap/.

Check kernel log:

dmesg | grep dma_heap

Expected log includes registration of the system heap.

Once DMA-BUF support is enabled and verified, use the same nib310rio, UHD, and FPGA image flow as the Linux desktop case.

Build and test UHD on Jetson

Build and install UHD using the same process as Linux desktop builds (see Building and Installing UHD from source).

After UHD and the driver are installed, validate operation:

uhd_find_devices --args type=b3xx
uhd_usrp_probe --args type=b3xx

Installing the Windows Kernel Driver

On Windows, install the b310k MSI driver package b310ki_win64.msi from Ettus UHD latest release binaries.

After installation, confirm the B310 appears in Device Manager and is enabled. If required, disable/enable the device from Device Manager to recover from enumeration failures after cabling or power changes.