宿主机安装

宿主机操作系统根据实际应用需求进行安装,详情参考NVIDIA SDK manager下载页。在此以Ubuntu22.04为例。

Host可以在实体机上安装,或是使用Vmware等虚拟机平台。使用Vmware时可以关闭Windows的Hyper-V虚拟机平台,并在Vmware中开启虚拟化以提升Vmware虚拟机性能。

安装依赖

sudo apt install git git-core build-essential bc flex bison libncurses-dev libssl-dev

下载并安装NVIDIA SDK Manager,需要登陆NVIDIA账号。

sudo dpkg -i sdkmanager.deb
sudo apt --fix-broken install #修复依赖

下载SDK

运行SDK Manager并登录,确保网络通畅,并确保系统时间准确,否则无法登录。
按需选择安装项目,此处仅安装JetPack对AGX Orin进行适配,Targer Hardware选择AGX Orin modules,SDK VERSION选择JetPack 6.2.1,不同JetPack版本在某些方面的配置差异较大。

在STEP2中:
Jetson Linux:用于AGX Orin开发的BSP,包含bootloader、kernel、rootfs等
Jetson Runtime Components:用于Jetson上CUDA运行时环境
Jetson SDK Components:用于Jetson上CUDA开发的工具
Jetson Platform Services:维护工具
对于固件适配来说,仅需要选择Jetson Linux即可。后续如需其它组件可以增量安装。

安装完成之后会来到烧录阶段,关闭SDK Manager即可。此时下载的SDK是缺少kernel源码的,需要使用SDK中的脚本来同步源码。需选择对于源码版本,此处以 jetpack6.2.1 为例,应选择 jetson_36.4.4 ,详细版本可以在官网找到 ,jetson-linux版本

export PATH_TO_SDK="/home/"${USER}"/nvidia/nvidia_sdk/"JetPack_6.2.1_Linux_JETSON_AGX_ORIN_TARGETS/Linux_for_Tegra
cd ${PATH_TO_SDK}/source
./source_sync.sh -k -t jetson_36.4.4 #同步内核源码

下载编译器

Jetson Linux Archive上下载jetson_36.4.4版本对应的编译器GCC 11.3

cd ${PATH_TO_SDK}/..
wget https://developer.nvidia.com/downloads/embedded/l4t/r36_release_v3.0/toolchain/aarch64--glibc--stable-2022.08-1.tar.bz2
tar -xvf aarch64--glibc--stable-2022.08-1.tar.bz2

设置环境变量

export CROSS_COMPILE_AARCH64_PATH=${PATH_TO_SDK}/../aarch64--glibc--stable-2022.08-1
export CROSS_COMPILE=$CROSS_COMPILE_AARCH64_PATH"/bin/aarch64-buildroot-linux-gnu-" #交叉编译器路径及前缀
export KERNEL_HEADERS=${PATH_TO_SDK}"/source/kernel/kernel-jammy-src" #内核源码路径
export INSTALL_MOD_PATH=${PATH_TO_SDK}"/rootfs" #根文件系统位置
export KERNEL_OUTPUT=${PATH_TO_SDK}"/kernel_out" #内核编译输出路径

检查交叉编译器是否生效:

${CROSS_COMPILE}gcc --version

正确的输出结果如下:

如下图所示,为该次用到的交叉编译器:

bin目录里为编译工具,include为头文件,主要关注bin目录,内容如下所示:

在交叉编译时,会调用 ${CROSS_COMPILE}gccCROSS_COMPILE 表示了编译工具的路径及前缀 aarch64-buildroot-linux-gnu-CROSS_COMPILE 完整的展开为:/home/hilinx/nvidia/nvidia_sdk/"JetPack_6.2.1_Linux_JETSON_AGX_ORIN_TARGETS/aarch64--glibc--stable-2022.08-1/bin/aarch64-buildroot-linux-gnu-,在调用 ${CROSS_COMPILE}gcc 时实则是执行 /home/hilinx/nvidia/nvidia_sdk/"JetPack_6.2.1_Linux_JETSON_AGX_ORIN_TARGETS/aarch64--glibc--stable-2022.08-1/bin/aarch64-buildroot-linux-gnu-gcc,若要执行 g++,则使用 ${CROSS_COMPILE}-g++

KERNEL_HEADERS、INSTALL_MOD_PATH、KERNEL_OUTPUT 均在sdk中 Makefile 中识别,若不定义KERNEL_OUTPUT 则会使用内核源码目录作为编译输出。INSTALL_MOD_PATH 为 内核模块安装位置,指向rootfs即可,KERNEL_HEADERS 需要指向内核源码位置。

设备树适配

Pinmux & GPIO

自定义载板中使用HDMI2输出,需要先对引脚进行配置,可以使用NVIDIA提供的配置工具(基于Excel编程)。

该工具需要在Windows MS Office中使用,不兼容LibreOffice/OnlyOffice等Office程序。如下所示,将DP2_HPD引脚功能改为GPIO并开启上拉电阻。

将HDMI_DP2_*的引脚功能全部配置为HDMI功能。

点击顶部的 Generate DT FIle 即可生成dts文件。
使用*-pinmux.dtsi替换${PATH_TO_SDK}/bootloader/tegra234-mb1-bct-pinmux-p3701-0000-a04.dtsi中的内容,注意保持include"tegra234-mb1-bct-gpio-p3701-00o0-a04.dtsi"不变。
使用*-gpio-default.dtsi替换${PATH_TO_SDK}/bootloader/generic/BCT/tegra234-mb1-bct-gpio-p3701-0000-a04.dtsi中的内容。

EEPROM

移除EEPROM识别。在官方的载板上有一颗EEPROM保存了一些配置信息,如果自定义载板没有这个EEPROM的话将会卡在bootloader启动阶段。

cd ${PATH_TO_SDK}
nano bootloader/tegra234-mb2-bct-common.dtsi

将62行中的EEPROM大小从0x100改为0x0。

HDMI

使用dcb_tool配置dcb。

cd ${PATH_TO_SDK}/tools/dcb_tool
cp ${PATH_TO_SDK}/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-dcb-p3737-0000-p3701-0000.dtsi ./
./dcb_tool -m tegra234-dcb-p3737-0000-p3701-0000.dtsi
// 依次选择:
Enter 1=> Modify DCB // 输入 1 修改DCB
Device Entries : 0   // 输入 0 通过设备入口修改
1                    // 选择设备 1
7                    // 修改 Connector 项
1                    // 修改为 1
y                    // 确认修改
1                    // 选择设备 1
9                    // 退出菜单
9                    // 退出程序

此时会输出一个 tegra234-dcb-p3737-0000-p3701-0000.dtsi-modified.dtsi 使用该文件替换掉 nv-platform 中的原文件即可。

cp tegra234-dcb-p3737-0000-p3701-0000.dtsi-modified.dtsi ${PATH_TO_SDK}/source/hardware/nvidia/t23x/nv-public/nv-platform/tegra234-dcb-p3737-0000-p3701-0000.dtsi

USB

官方载板USB有适配USB-C PD以及OTG模式,自定义载板则需要修改USB配置,将所有USB2.0、USB3.0端口配置为,位于 ${PATH_TO_SDK}/source/hardware/nvidia/t23x/nv-public/tegra234-p3737-0000+p3701-0000.dts。修改的时候需注意usb3-x中的 nvidia,usb2-companion = <x>; 需要绑定对应的usb2.0端口。

// USB端口配置
// 原配置
ports {
	usb2-0 {
		// ......
	}
	// ......
}
// 修改后
ports {
	usb2-0 {
		mode = "host";
		status = "okay";
	};
	usb2-1 {
		mode = "host";
		status = "okay";
	};
	usb2-2 {
		mode = "host";
		status = "okay";
	};
	usb2-3 {
		mode = "host";
		status = "okay";
	};
	usb3-0 {
		nvidia,usb2-companion = <1>;
		status = "okay";
	};
	usb3-1 {
		nvidia,usb2-companion = <2>;
		status = "okay";
	};
	usb3-2 {
		nvidia,usb2-companion = <3>;
		status = "okay";
	};
};
// I2C配置
// 原配置
i2c@c240000 {
	status = "okay";
	
	typec@8 {
		//......
	};
};
// 修改后
i2c@c240000 {
	status = "okay";
};

MGBE

如果载板上没有使用MGBE则需要禁用,不然会导致不开机

在 ${PATH_TO_SDK}/source/hardware/nvidia/t23x/nv-public/tegra234-p3737-0000+p3701-0000.dts 中,将 ethernet@6800000 的状态修改为 disable。

ethernet@6800000 {
			status = "disable";

			phy-handle = <&mgbe0_phy>;
			phy-mode = "10gbase-r";

			mdio {
				#address-cells = <1>;
				#size-cells = <0>;

				mgbe0_phy: phy@0 {
					compatible = "ethernet-phy-ieee802.3-c45";
					reg = <0x0>;

					#phy-cells = <0>;
				};
			};
		};

修改 ${PATH_TO_SDK}/p3701.conf.common 156行:

- ODMDATA="gbe-uphy-config-22,hsstp-lane-map-3,nvhs-uphy-config-0,hsio-uphy-config-0,gbe0-enable-10g";
+ ODMDATA="gbe-uphy-config-0,hsstp-lane-map-3,nvhs-uphy-config-0,hsio-uphy-config-0";

编译内核

cd ${PATH_TO_SDK}/source
mkdir ../kernel_out
sudo -E make -C kernel #编译内核
cp ../kernel_out/arch/arm64/boot/Image ${PATH_TO_SDK}/kernel/Image

编译 DTB

sudo -E make dtbs
cp kernel-devicetree/generic-dts/dtbs/* ${PATH_TO_SDK}/kernel/dtb/

编译模块

sudo -E make modules
cd ${PATH_TO_SDK} && sudo ./tools/l4t_update_initrd.sh #安装模块

XDMA驱动

Xilinx官方XDMA驱动仅适配x86平台,需要使用arm64移植版本的XDMA驱动。

cd ${PATH_TO_SDK}/source
wget https://res.hilinx.top/2025/06/20250618092530403.zip -O xdma_driver.zip
unzip xdma_driver.zip #将xdma源码下载到source目录
cd xdma_driver/xdma #解压
make

编译过程中会出现若干警告,编译成功后将会输出xdma.ko文件,使用file命令查看:

file xdma.ko

如下所示,为64位arm64可执行链接格式:

cp xdma.ko ../../../rootfs/tmp #将ko复制到rootfs

ROOTFS

通过chroot来编辑rootfs:

cd ${PATH_TO_SDK}
touch chroot-enter.sh
touch chroot-exit.sh
chmod +x chroot-*.sh

chroot-enter.sh

#!/bin/bash
ROOTFS="rootfs"

mounts=("proc" "sys" "dev" "dev/pts" "run")
for mnt in "${mounts[@]}"; do
  mount -o bind "/$mnt" "$ROOTFS/$mnt" || mount -t "$mnt" "$mnt" "$ROOTFS/$mnt"
done

mv $ROOTFS/etc/resolv.conf $ROOTFS/etc/resolv.conf.bak
cp /etc/resolv.conf $ROOTFS/etc/
cp /usr/bin/qemu-*-static $ROOTFS/usr/bin/
chroot $ROOTFS /bin/bash

chroot-exit.sh

#!/bin/bash
ROOTFS="rootfs"

umount $ROOTFS/{proc,sys,dev/pts,dev,run}
rm $ROOTFS/usr/bin/qemu-*-static
mv $ROOTFS/etc/resolv.conf.bak $ROOTFS/etc/resolv.conf

通过chroot-enter.sh进入chroot,退出chroot后务必执行一次chroot-exit.sh用于恢复resolv.conf。

sudo ./chroot-enter.sh // chroot进入rootfs

#卸载多余软件
apt purge transmission-gtk gnome-todo cheese aisleriot gnome-mahjongg gnome-mines gnome-sudoku onboard simple-scan snapd thunderbird -y
apt autopurge -y

#更换软件源
rm /etc/apt/sources.list
echo "# 默认注释了源码仓库,如有需要可自行取消注释
deb https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy main restricted universe multiverse

deb https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy-security main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy-security main restricted universe multiverse

deb https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy-updates main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy-updates main restricted universe multiverse

deb https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy-backports main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy-backports main restricted universe multiverse

# 预发布软件源,不建议启用
# deb https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy-proposed main restricted universe multiverse
# deb-src https://mirrors.ustc.edu.cn/ubuntu-ports/ jammy-proposed main restricted universe multiverse" > /etc/apt/sources.list

apt update
apt upgrade

# 安装xdma内核模块
mkdir -p -m 755 /lib/modules/5.15.148-tegra/xdma
install -v -m 644 /tmp/xdma.ko /lib/modules/5.15.148-tegra/xdma
rm /tmp/xdma.ko
depmod -a 5.15.148-tegra || true

# 禁用snap商店
echo '
Package: snapd
Pin: release a=*
Pin-Priority: -10
' | tee /etc/apt/preferences.d/nosnap.pref

# 安装firefox
install -d -m 0755 /etc/apt/keyrings
wget -q https://packages.mozilla.org/apt/repo-signing-key.gpg -O- |tee /etc/apt/keyrings/packages.mozilla.org.asc > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/packages.mozilla.org.asc] https://packages.mozilla.org/apt mozilla main" | tee -a /etc/apt/sources.list.d/mozilla.list > /dev/null
echo '
Package: *
Pin: origin packages.mozilla.org
Pin-Priority: 1000
' | tee /etc/apt/preferences.d/mozilla 
apt update
apt install firefox -y

#安装vscode
wget https://vscode.download.prss.microsoft.com/dbazure/download/stable/dfaf44141ea9deb3b4096f7cd6d24e00c147a4b1/code_1.101.0-1749655353_arm64.deb
dpkg -i code_1.101.0-1749655353_arm64.deb
rm code_1.101.0-1749655353_arm64.deb
apt clean #清理apt缓存

#安装CUDA环境
apt install nvidia-jetpack

#添加nvcc到环境变量
echo 'export PATH=$PATH:/usr/local/cuda/bin' >> /root/.bashrc
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64' >> /root/.bashrc

烧录

SDK Manager 在烧录固件时,会引用以下路径或文件

  1. ${PATH_TO_SDK}/kernel/dtb/ # 设备树
  2. ${PATH_TO_SDK}/kernel/Image # 内核镜像

将以上文件打包生成烧录所需镜像文件,位于 ${PATH_TO_SDK}/bootloader/ 中,包括 system.img recovery.img boot.img 等。因此编译dtb和kernel后,会使用编译输出的dtb和Image复制替换掉上述路径中的文件,已便 SDK Manager 打包镜像时使用编译输出的文件。

注意事项

  1. Linux_for_Tegra中的rootfs为Jetson的根目录文件,在移动、复制、打包SDK时请务必保留权限和属性。
  2. 使用sudo编译时务必带 -E 参数,否则环境变量不会生效,将会导致交叉编译失败。
  3. 每次打开terminal时需要加载环境变量,确保编译过程中环境变量有效。
  4. rtl8188eu 驱动,仅用于 agx orin。