Custom Jetson Linux Kernel

Note

The custom kernel is only required for NVIDIA Jetson platforms (AGX Orin, Orin Nano). The AGX Thor requires a custom kernel only if connecting the Quectel modem as user equipment (qmi_wwan). The DGX Spark does not require kernel modifications.

The 5G core network requires SCTP (Stream Control Transmission Protocol) support in the Linux kernel. Additionally, connecting a Quectel modem via USB requires the qmi_wwan kernel module. By default, these are not enabled in the Jetson Linux kernel. This guide walks through building a custom Linux kernel that includes these features.

This guide is based on the Jetson Linux Kernel Configuration Guide. The following instructions deviate from the original in a few points:

  • We do not use the Bootlin toolchain (11.3) but use the provided Ubuntu GCC compiler instead, since we are not cross-compiling

  • We add the SCTP network protocol and USB modem drivers as modules

  • We enable advanced routing in the kernel

  • We do not recompile the DTBs (Device Tree Blobs). The system’s device tree remains unchanged

  • We backup the original installation; we do not override it

Note

It is highly recommended NOT to perform these steps as root. Use sudo only when necessary for specific steps.

Manual Build

For advanced users who want more control over the build process, the following sections describe the manual steps.

Prerequisites

Install the required build tools:

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

Source Code

Download and extract the kernel source packages. The exact URL depends on your L4T version:

# Create build directory
mkdir -p ext/l4t && cd ext/l4t

# Download sources (example for L4T 36.4.3)
wget https://developer.nvidia.com/downloads/embedded/l4t/r36_release_v4.3/sources/public_sources.tbz2

# Extract source packages
tar xf public_sources.tbz2
cd Linux_for_Tegra/source

# Expand required sources
tar xf kernel_src.tbz2
tar xf kernel_oot_modules_src.tbz2
tar xf nvidia_kernel_display_driver_source.tbz2

Kernel Configuration

The kernel configuration options are stored in l4t/kernel/config.options:

CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_INET_SCTP_DIAG=m
CONFIG_IP_SCTP=m
CONFIG_NETFILTER_XT_MATCH_SCTP=m
CONFIG_NF_CT_PROTO_SCTP=y
CONFIG_SCTP_COOKIE_HMAC_MD5=y
CONFIG_SCTP_DEFAULT_COOKIE_HMAC_MD5=y
CONFIG_USB_NET_DRIVERS=y
CONFIG_USB_NET_CDCETHER=m
CONFIG_USB_NET_CDC_NCM=m
CONFIG_USB_NET_CDC_MBIM=m
CONFIG_USB_NET_QMI_WWAN=m
CONFIG_USB_WDM=m
CONFIG_USB_SERIAL_WWAN=m

These enable:

  • SCTP protocol: Required for 5G core network communication

  • Advanced routing: Required for proper network configuration

  • USB network drivers: Required for Quectel modem connectivity (qmi_wwan)

To apply these options manually, navigate to the kernel source directory and use the kernel config scripts:

cd Linux_for_Tegra/source/kernel/kernel-jammy-src  # or kernel-noble for Thor

# Start from default config
make mrproper
make defconfig

# Apply each option (example)
./scripts/config --file .config --set-val CONFIG_IP_SCTP m
# ... repeat for other options

# Resolve dependencies
make olddefconfig

Building the Kernel

cd Linux_for_Tegra/source

# Build the kernel
make -C kernel

# Create temporary rootfs directories
mkdir -p Linux_for_Tegra/rootfs/boot
mkdir -p Linux_for_Tegra/rootfs/kernel

# Set module installation path
export INSTALL_MOD_PATH=$PWD/../rootfs

# Install kernel
sudo -E make install -C kernel

# Set kernel headers path (adjust for your Ubuntu version)
export KERNEL_HEADERS=$PWD/kernel/kernel-jammy-src  # or kernel-noble

# For Thor (Noble), also set:
export kernel_name=noble

# Build and install modules
make modules
sudo -E make modules_install

Installing the Kernel

Warning

Back up your existing kernel before proceeding. Package updates may overwrite custom kernels.

# Backup existing kernel and modules
sudo cp /boot/Image /boot/Image.original
sudo cp /boot/initrd /boot/initrd.original
sudo cp -r /lib/modules/$(uname -r) /lib/modules/$(uname -r).original

# Install new kernel
sudo cp Linux_for_Tegra/rootfs/boot/Image /boot/Image

# Install new modules
sudo cp -r Linux_for_Tegra/rootfs/lib/modules/$(uname -r) /lib/modules/

# Update initrd and boot configuration
sudo nv-update-initrd
sudo nv-update-extlinux generic

Boot Configuration (Optional)

For more control over boot options, you can manually edit the extlinux configuration. This is equivalent to editing grub.conf on a standard system and allows you to boot the system to the old kernel if necessary.

Note

This example assumes the system uses an NVMe SSD (root=/dev/nvme0n1p1). Adjust as needed for your setup.

cd /boot/extlinux

# Backup current configuration
sudo cp extlinux.conf extlinux.conf.original

Edit extlinux.conf to add boot entries. Example configuration:

TIMEOUT 30
DEFAULT primary

MENU TITLE L4T boot options

LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image
      INITRD /boot/initrd
      APPEND ${cbootargs} root=/dev/nvme0n1p1 rw rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 console=ttyAMA0,115200 firmware_class.path=/etc/firmware fbcon=map:0 net.ifnames=0 nospectre_bhb video=efifb:off console=tty0 nv-auto-config

LABEL original
      MENU LABEL original precompiled kernel
      LINUX /boot/Image.original
      INITRD /boot/initrd.original
      APPEND ${cbootargs} root=/dev/nvme0n1p1 rw rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 console=ttyAMA0,115200 firmware_class.path=/etc/firmware fbcon=map:0 net.ifnames=0 nospectre_bhb video=efifb:off console=tty0 nv-auto-config

Change the DEFAULT entry to the label you want to use and reboot.

Verification

After rebooting, verify the modules are available:

# Check for SCTP module
modinfo sctp

# Check for Quectel modem driver
modinfo qmi_wwan

# Load modules
sudo modprobe sctp
sudo modprobe qmi_wwan

# List loaded modules
lsmod | grep -E "sctp|qmi"