How to port a driver to JetPack6.0

From RidgeRun Developer Wiki
Revision as of 19:35, 24 May 2024 by Spalli (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)



Download Linux_for_Tegra and the sources for JetPack6.0

To download Linux_for_Tegra open your SDKmanager, set the target hardware (Orin NX in my case) and select JetPack 6.0 DP as shown in the following picture

Click on continue, accept the terms and conditions on the next tab and click on continue again

After these steps are done you can skip the rest of the steps on the SDKmanager

You should have the following directory created on your computer. The directory is named according to the target hardware set on the SDKmanager so please make sure the name matches the configuration of the SDKmanager

~/nvidia/nvidia_sdk/JetPack_6.0_DP_Linux_DP_JETSON_ORIN_NX_TARGETS

Download Nvidia's Driver Package (BSP) Sources from the linux-archive: https://developer.nvidia.com/embedded/jetson-linux-r362

Or directly download it from the following link: public_sources.tbz2

For extracting the kernel and the NVIDIA out-of-tree modules from the public sources:

tar -xjf public_sources.tbz2 Linux_for_Tegra/source/kernel_src.tbz2 --strip-components 2
tar -xjf public_sources.tbz2 Linux_for_Tegra/source/kernel_oot_modules_src.tbz2 --strip-components 2
tar -xjf public_sources.tbz2 Linux_for_Tegra/source/nvidia_kernel_display_driver_source.tbz2 --strip-components 2

Go to the Linux_for_Tegra directory

cd ~/nvidia/nvidia_sdk/JetPack_6.0_DP_Linux_DP_JETSON_ORIN_NX_TARGETS/Linux_for_Tegra

Then extract the kernel and the NVIDIA out-of-tree modules sources in the sources directory

mkdir sources
tar -xjf kernel_src.tbz2 -C sources
tar -xjf kernel_oot_modules_src.tbz2 -C sources
tar -xjf nvidia_kernel_display_driver_source.tbz2 -C sources

This extracts the kernel source to the sources/kernel/ subdirectory and the NVIDIA Out-of-Tree kernel modules sources to the sources directory

After the steps above are done, your directory should look like the following:

~/nvidia/nvidia_sdk/JetPack_6.0_DP_Linux_DP_JETSON_ORIN_NX_TARGETS/Linux_for_Tegra/sources$ tree -L 1
.
├── generic_rt_build.sh
├── hardware
├── hwpm
├── kernel
├── kernel_src_build_env.sh
├── Makefile
├── nvbuild.sh
├── nvcommon_build.sh
├── nvdisplay
├── nvethernetrm
├── nvgpu
├── nvidia-oot
└── README.md

Set the development environment for building the kernel, device tree and modules

Install dependencies in the host PC

  1. Make sure the following dependencies are installed on your system:
    • wget
    • lbzip2
    • build-essential
    • bc
    • zip
    • libgmp-dev
    • libmpfr-dev
    • libmpc-dev
    • vim-common # For xxd

In Debian based systems you can run the following:

sudo apt install wget lbzip2 build-essential bc zip libgmp-dev libmpfr-dev libmpc-dev vim-common

Get the Toolchain

If you haven't already, download the toolchain. The toolchain is the set of tools required to cross-compile the Linux kernel. You can download the Bootlin Toolchain gcc 11.3 from the linux-archive: https://developer.nvidia.com/embedded/jetson-linux-r362

Or directly download it from the following link: aarch64--glibc--stable-2022.08-1

Then, extract the files in the following directory

cd $HOME
mkdir -p $HOME/l4t-gcc
cd $HOME/l4t-gcc

tar -xjf aarch64--glibc--stable-2022.08-1

Export the environment variables

Open a terminal and run the following commands to export the environment variables that will be used in the next steps. Please keep in mind that if the sources are in a different directory than the one defined in DEVDIR, a different DEVDIR needs to be defined, always pointing at the directory where the Linux_for_Tegra folder is.

export DEVDIR=~/nvidia/nvidia_sdk/JetPack_6.0_DP_Linux_DP_JETSON_ORIN_NX_TARGETS/Linux_for_Tegra

export CROSS_COMPILE=$HOME/l4t-gcc/aarch64--glibc--stable-2022.08-1/bin/aarch64-buildroot-linux-gnu-
export INSTALL_MOD_PATH=$DEVDIR/rootfs/
export KERNEL_HEADERS=$DEVDIR/sources/kernel/kernel-jammy-src

Compile the kernel, device tree and modules

  • Go to the kernel directory
cd $DEVDIR/sources/kernel/kernel-jammy-src
  • Execute the default configuration. You can enable any kernel configuration if you wish.
make menuconfig
  • Go to the sources directory
cd $DEVDIR/sources
  • Compile the kernel
make -C kernel
  • Install the kernel
sudo -E make install -C kernel
  • Compile the dtb
make dtbs
  • Install the dtb
cp nvidia-oot/device-tree/platform/generic-dts/dtbs/* $DEVDIR/kernel/dtb/
  • Compile the Out-of-Tree modules
make modules
  • Install the modules
sudo -E make modules_install

After these steps are done you will have compiled the base kernel, device tree and modules for JetPack6.0

Add your driver to JetPack6.0 sources

Let's keep in mind how the sources directory tree looks:

~/nvidia/nvidia_sdk/JetPack_6.0_DP_Linux_DP_JETSON_ORIN_NX_TARGETS/Linux_for_Tegra/sources$ tree -L 2
.
├── generic_rt_build.sh
├── hardware
│   └── nvidia
├── hwpm
├── kernel
│   ├── kernel-jammy-src
│   └── Makefile
├── kernel_src_build_env.sh
├── Makefile
├── nvbuild.sh
├── nvcommon_build.sh
├── nvdisplay
├── nvethernetrm
├── nvgpu
├── nvidia-oot
│   ├── arch
│   ├── device-tree
│   ├── dkms.conf
│   ├── Documentation
│   ├── drivers
│   ├── include
│   ├── Makefile
│   ├── Makefile-dkms
│   ├── modules.order
│   ├── Module.symvers
│   ├── scripts
│   ├── sound
│   └── tools
└── README.md

Driver

Back in JetPack 5 era, drivers were directly integrated into NVIDIA’s downstream kernel (either built directly into the kernel image or built as in-tree module), but NVIDIA wants to align with the upstream kernel so users can choose the kernel version on their own. This means that a lot of drivers are being pulled out from the kernel source, which must be compiled separately as out-of-tree modules.

For example, if you are developing a camera driver you would expect that the driver.c code is located in the following directory

$DEVDIR/sources/kernel/nvidia/drivers/media/i2c/driver.c

Not anymore. With the new Out-of-Tree modules scheme the drivers code is located at the following directory

$DEVDIR/sources/nvidia-oot/drivers/media/i2c/driver.c

In general, a bunch of drivers are being pull out from the kernel directory to the nvidia-oot directory. If you are looking for a specific driver that you don't know if it was moved out-of-tree or if it remains in-tree, I recommend you to do a find . | grep <driver_name> in the $DEVDIR/sources directory.

With that said, these are the modifications required for adding the driver to JetPack6.0 sources:

  • On $DEVDIR/sources/kernel/kernel-jammy-src/arch/arm64/configs/defconfig add
CONFIG_NV_VIDEO_DRIVER_NAME=m
  • On $DEVDIR/sources/nvidia-oot/drivers/media/i2c/Makefile add
obj-m += driver_name.o
  • On $DEVDIR/sources/kernel/kernel-jammy-src/drivers/media/i2c/Kconfig add
config NV_VIDEO_DRIVER_NAME
	tristate "XXtextXX MIPI CSI-2 camera sensor support XXtextXX"
	depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
	help
	  This is a Video4Linux2 sensor driver for the Vision Components
	  MIPI CSI-2 camera sensor, for use with the tegra isp.

	  To compile this driver as a module, choose M here: the module
	  will be called driver_name.
  • On $DEVDIR/sources/nvidia-oot/drivers/media/i2c/ add your driver
driver_name.c

After those modifications are done, you can build the driver module.

Device Tree

In JetPack6.0 the device tree is structured as two distinct layers:

  • The bottom layer comes from the upstream Linux kernel, which keeps the NVIDIA sources aligned with the upstream.

These files are in the root of the nv-public folder (for example nv-public/tegra234-p3768-0000+p3767-0005.dts).

  • The top layer comes from the nv-platform directory.

The main dts file for each platform is named to coincide with the upstream dts file. However, instead of <board>.dts it is <board>-nv.dts. For example, the nv-public/nv-platform/tegra234-p3768-0000+p3767-0005-nv.dts file includes the upstream dts file and also adds content and updates.

Add camera modules to a device tree

According to the documentation you can create a tegra-camera-platform device tree node in the kernel source tree. In order to check the definition for each of the module's properties please check the official documentation at: Camera Modules and the Device Tree

After the device tree is made, move it to the following directory:

$DEVDIR/hardware/nvidia/t23x/nv-public/overlay

Finally, rebuild the device tree

Using the Main Platform Device Tree File

According to the documentation in order to register a device using the main platform device tree you need to

  • Locate and edit the .dtsi file:
$DEVDIR/hardware/nvidia/t23x/nv-public/overlay/tegra234-p3737-0000+p3701-0000-dynamic.dts
  • Replace the following line:
#include "tegra234-p3737-camera-modules.dtsi"

With an #include statement specifying the .dtsi file for your new device.

Finally, rebuild your device tree

What I did and currently works

I checked which device tree was my board using, in my case I was using an Orin NX and the device tree it uses is the following

tegra234-p3768-0000+p3767-0000-nv.dtb

I found the respective .dts file at

$DEVDIR/sources/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-p3768-0000+p3767-0000-nv.dts

In that device tree I included my camera device tree

#include "tegra234-camera-vc-mipi-cam.dtsi"

On the directory $DEVDIR/sources/hardware/nvidia/t23x/nv-public/nv-platform/ add your camera device tree file

tegra234-camera-vc-mipi-cam.dtsi

On $DEVDIR/sources/hardware/nvidia/t23x/nv-public/nv-platform/Makefile check that the device tree is added to the Makefile

dtb-y += tegra234-p3768-0000+p3767-0000-nv.dtb

After these modifications are done you can proceed to rebuild the kernel, device tree and modules as explained in the section Compile the kernel, device tree and modules

Finally, after rebuilding the kernel, device tree and modules you can proceed to copy those files to their respective paths on your Jetson or you can fully reflash the board as you wish.


RidgeRun Resources

Quick Start Client Engagement Process RidgeRun Blog Homepage
Technical and Sales Support RidgeRun Online Store RidgeRun Videos Contact Us
RidgeRun.ai: Artificial Intelligence | Generative AI | Machine Learning

Contact Us

Visit our Main Website for the RidgeRun Products and Online Store. RidgeRun Engineering information is available at RidgeRun Engineering Services, RidgeRun Professional Services, RidgeRun Subscription Model and Client Engagement Process wiki pages. Please email to support@ridgerun.com for technical questions and contactus@ridgerun.com for other queries. Contact details for sponsoring the RidgeRun GStreamer projects are available in Sponsor Projects page.