博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持!
博主链接
本人就职于国际知名终端厂商,负责modem芯片研发。
在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。
博客内容主要围绕:
5G/6G协议讲解
算力网络讲解(云计算,边缘计算,端计算)
高级C语言讲解
Rust语言讲解
文章目录
- Jetson AGX Orin内核、设备树更新指南
- 一、下载工具包和内核源码
- 1.1 下载工具包
- 1.2 安装依赖并下载内核源代码
- 二、准备编译环境
- 2.1 安装编译工具链
- 2.2 安装内核工具包
- 三、编译内核
- 四、编译NVIDIA驱动
- 五、更新内核和设备树文件
- 5.1 使用官方flash.sh脚本刷新系统
- 5.1.1 环境准备
- 5.1.2 准备rootfs
- 5.1.3 将编译的产物拷贝到特定的位置
- 5.1.4 开始刷机
- 5.2 只更新内核和设备树(非刷机方式)
- 5.2.1 备份并更新内核
- 5.2.2 备份并更新设备树文件
- 5.3 使用flash.sh脚本更新内核和设备树
- 六、设备备份与恢复
- 6.1 环境准备
- 6.2 备份环境(大约1h)
- 6.3 恢复环境
- 附录
- 1. 编译内核时遇到的问题
- 2. 如何进入恢复模式
- 2.1 设别关闭情况下
- 2.2 设备上电情况下
- 3. 调试串口和刷机下载接口
Jetson AGX Orin内核、设备树更新指南
注意:最好使用Ubuntu20.04,如果使用的是Ubuntu22.04则需要使用docker
一、下载工具包和内核源码
1.1 下载工具包
访问Jetson Download Center,下载最新版本的SDK Manage。
下载后安装sdkmanage,然后允许下面的命令,将需要的数据包都下载下来(记住不需要刷新jetson,只选择下载稍后安装即可,见下图)。
$ ./sdkmanage
下载完成后可以在默认的下载位置($HOME/Download)可以看到一个压缩包,Jetson_Linux_R35.3.1_aarch64.tbz2(撰写此文档的时候最新版本的R35.3.1),这个包里面包含了很多用于开发的工具和源代码,其中包含了脚本source_sync.sh可以用于自动同步和下载内核源代码。(也可以通过访问Jetson Linux home page下载Driver Package(BSP)但可能不是最新版本)
解压缩该文件,解压后的文件目录结构如下图所示,其中Linux_for_Tegra是解压出来的文件夹:
1.2 安装依赖并下载内核源代码
如果系统中没有git,可以运行下面的命令安装git:
$ sudo apt install git-core
将上述压缩包解压后,在Linux_for_Tegra文件夹下运行:
$ ./source_sync.sh
就会自动同步下载内核源代码,下载过程中会要求输入tag,也可以直接输入下面的命令,直接不同步到jetson_35.3.1:
$ ./source_sync.sh -t jetson_35.3.1
下载完成后的目录结构如下图所示,其中sources中包含了内核和设备树源码:
在内核代码仓中运行下面的命令可以查看所有可用的tag:
$ git tag -l
二、准备编译环境
2.1 安装编译工具链
访问Jetson Linux home page,下载工具链压缩包:
然后运行下面的命令:
$ mkdir $HOME/l4t-gcc
$ cd $HOME/l4t-gcc
$ tar -xf <toolchain_archive>
最后设置环境变量(临时生效,重启系统或者cmd之后需要重新输入):
$ export CROSS_COMPILE=$HOME/l4t-gcc/bin/aarch64-buildroot-linux-gnu-
2.2 安装内核工具包
访问Jetson Linux home page,下载最新版本的Jetson Linux Source:
这个工具包中包含了kernel、dtbs、kernel header,以及用于编译内核的脚本文件nvbuild.sh。解压pubilc_sources.tbz2后找到kernel_src.tbz2继续解压文件。解压后将nvbuild.sh、nvcommon_build.sh拷贝到通过source_sync.sh下载的内核<path-to>/Linux_for_Tegra/sources
目录下。
三、编译内核
- 安装基础软件包:
$ sudo apt install build-essential bc flex bison libncurses-dev libssl-dev
- 配置交叉编译环境
$ export CROSS_COMPILE_AARCH64_PATH=$HOME/l4t-gcc
$ export CROSS_COMPILE_AARCH64=$HOME/l4t-gcc/bin/aarch64-buildroot-linux-gnu-
- 创建内核编译文件的保存目录:
$ mkdir $HOME/kernel_output
- 运行下面的命令开始编译内核
$ ./nvbuild.sh -o $HOME/kernel_output
四、编译NVIDIA驱动
- 从2.2节解压的public_sources.tbz2中找到nvidia_kernel_display_driver_source.tbz2压缩包,并解压缩,目录结构如下图所示:
- 设置环境变量:
$ export CROSS_COMPILE_AARCH64=$HOME/l4t-gcc/bin/aarch64-buildroot-linux-gnu-
$ export LOCALVERSION="-tegra"
- 进入解压缩后的文件夹,并执行下面的命令:
$ make modules SYSSRC=<path-to>/Linux_for_Tegra/sources/kernel/kernel-<version> SYSOUT=$HOME/kernel_output CC=${CROSS_COMPILE_AARCH64}gcc LD=${CROSS_COMPILE_AARCH64}ld.bfd AR=${CROSS_COMPILE_AARCH64}ar CXX=${CROSS_COMPILE_AARCH64}g++ OBJCOPY=${CROSS_COMPILE_AARCH64}objcopy TARGET_ARCH=aarch64 ARCH=arm64
编译后的产物存储在$HOME/kernel_output
中,如下图所示:
五、更新内核和设备树文件
Jetson AGX Orin默认的配置文件位于:/Jetson_for_Linux/sources/kernel/kernel-5.10/arch/arm64/config/tegra_defconfig
5.1 使用官方flash.sh脚本刷新系统
也是官方建议的方法,时间大约15~20min。注意备份文件,系统会被擦除。
5.1.1 环境准备
通过Jetson提供的flash.sh(位于Linux_for_Tegra目录内)脚本来完成内核和设备树的更新(其实是刷机),首先需要安装flash.sh需要的库:
$ cd <path-to>/Linux_for_Tegra
$ sudo tools/l4t_flash_prerequisites.sh
5.1.2 准备rootfs
- 访问Jetson Linux home page,下载rootfs压缩包,如下图所示,然后解压缩到
\<path-to>/Linux_for_Tegra/rootfs
(注意需要使sudo进行解压缩)
- 执行下面的命令安装NVIDIA扩展bin文件:
$ sudo ./apply_binaries.sh
- 创建一个用于x,密码为1,并设置自动登录(这一步是避免刷机后没有图新界面需要通过串口创建用户时的不稳定,这里的用户名和密码需要改成您自己的):
$ sudo ./tools/l4t_create_default_user.sh -u x -p 1 -a
5.1.3 将编译的产物拷贝到特定的位置
- 执行下面的命令,拷贝编译内核的产物:
$ sudo cp $HOME/kernel_output/drivers/gpu/nvgpu/nvgpu.ko <path-to>/Linux_for_Tegra/rootfs/usr/lib/modules/$(uname -r)/kernel/drivers/gpu/nvgpu/nvgpu.ko
$ sudo cp -r $HOME/kernel_output/arch/arm64/boot/dts/nvidia <path-to>/Linux_for_Tegra/kernel/dtb/
$ sudo cp $HOME/kernel_output/arch/arm64/boot/Image <path-to>/Linux_for_Tegra/kernel/Image
- 在 $HOME/kernel_output 目录下执行:
$ sudo make ARCH=arm64 O=$HOME/kernel_output modules_install INSTALL_MOD_PATH=<path-to>/Linux_for_Tegra/rootfs/
- 执行下面的命令,拷贝编译NVIDIA驱动的产物(nvidia-drm.ko、nvidia.ko、nvidia-modeset.ko):
$ sudo mkdir -p <path-to>/Linux_for_Tegra/rootfs/lib/modules/$(uname -r)/extra/opensrc-disp
$ sudo cp <path-to>/NVIDIA-kernel-module-source-TempVersion/kernel-open/*.ko <path-to>/Linux_for_Tegra/rootfs/lib/modules/$(uname -r)/extra/opensrc-disp
5.1.4 开始刷机
- 按照附录-2进入恢复模式
- 执行下面的命令:
$ sudo ./flash.sh jetson-agx-orin-devkit internal
- 【可选】刷机后第一次开机,如果没有图形界面,需要通过串口输入
$ sudo depmod -a
然后重新启动Jetson,图形界面就回来了。
5.2 只更新内核和设备树(非刷机方式)
这个方法是我自己尝试的,目前没有发现问题
5.2.1 备份并更新内核
- 修改jetson板块中的
/boot/extlinux/extlinux.conf
文件,备份现在使用的内核,修改后的文件内容如下所示:
TIMEOUT 100
DEFAULT primaryMENU TITLE L4T boot optionsLABEL primaryMENU LABEL primary kernelLINUX /boot/ImageFDT /boot/dtb/kernel_tegra234-p3701-0000-p3737-0000.dtbINITRD /boot/initrdAPPEND ${cbootargs} root=PARTUUID=0c4e1692-9ba5-4a6d-8192-2091bb0a3a35 rw rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 console=ttyAMA0,115200 firmware_class.path=/etc/firmware fbcon=map:0 net.ifnames=0 LABEL backupMENU LABEL primary kernelLINUX /boot/Image.backupFDT /boot/dtb/kernel_tegra234-p3701-0000-p3737-0000.dtbINITRD /boot/initrdAPPEND ${cbootargs} root=PARTUUID=0c4e1692-9ba5-4a6d-8192-2091bb0a3a35 rw rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 console=ttyAMA0,115200 firmware_class.path=/etc/firmware fbcon=map:0 net.ifnames=0
注意不要完全拷贝,看懂怎么改的是关键,有些参数可以是不同的,例如root的PARTUUID
- 将原始的内核镜像进行备份:
$ sudo cp /boot/Image /boot/Image.backup
- 通过
scp
命令将新内核拷贝到Jetson的/boot/Image
- 创建一个文件夹,例如
$ mkdir <path-to>/manual_update_kernel
$ sudo make ARCH=arm64 O=$HOME/kernel_output modules_install INSTALL_MOD_PATH=<path-to>/manual_update_kernel
- 将第四节编译的NVIDIA驱动,拷贝到manual_update_kernel的对应文件夹中。将
nvgpu.ko
也拷贝到对应的位置(参见5.1.3-1) - 将
manual_update_kernel/lib/modules
下的文件打包,拷贝到jetson板卡后,替换对应位置的文件夹(/lib/modules/$(uname -r)
) - 重启系统,在重启过程中会要求用户选择一个内核镜像。选择0就是新的内核镜像,1是备份内核镜像
- 执行下面的命令,并重启jetson
$ sudo depmod -a
5.2.2 备份并更新设备树文件
- 修改完设备树文件之后,重新编译内核,编译完成后会在
$HOME/kernel_output/arch/arm64/boot/dts/nvidia
目录下生成一个tegra234-p3701-0000-p3737-0000.dtb文件 - 将上述文件拷贝到Jetson板卡的
/boot/dtb
目录下 - 修改
extlinux.conf
文件中的FDT
参数的值,使其指向正确的设备树文件
5.3 使用flash.sh脚本更新内核和设备树
- 可以通过下面的命令更新分区中的内核和设备树
$ sudo ./flash.sh -r -k A_kernel -k A_kernel_dtb jetson-agx-orin-devkit internal
注意:UEFI会优先使用/boot/extlinux/extlinux.conf文件中获取的image和dtb。如果在该文件中没有提到image和dtb,才会使用位于eMMC分区中的image和dtb。所以如果extlinux.conf中内置了image和dtb,则执行上述指令后,下次重启还是会使用原来的image和dtb。
六、设备备份与恢复
Jetson的BSP工具包携带了自动备份和恢复的工具,位于<path-to>/Linux_for_Tegra/tools/backup-restore/
内。
注意:需要首先进入设备恢复模式(参见附录-2)
6.1 环境准备
$ sudo systemctl stop udisks2.service
$ sudo tools/l4t_flash_prerequisites.sh
$ sudo service nfs-kernel-server start
6.2 备份环境(大约1h)
$ cd <path-to>/Linux_for_Tegra
$ sudo ./tools/backup_restore/l4t_backup_restore.sh -b jetson-agx-orin-devkit
备份完成后,会自动重启。备份后的文件存储在<path-to>/Linux_for_Tegra/tools/backup-restore/images
中。
6.3 恢复环境
$ cd <path-to>/Linux_for_Tegra
$ sudo ./tools/backup_restore/l4t_backup_restore.sh -r jetson-agx-orin-devkit
附录
1. 编译内核时遇到的问题
drivers/video/Kconfig.27:can’t open file “drivers/video/tegra/Kconfig”
可以参考链接解决。
2. 如何进入恢复模式
2.1 设别关闭情况下
- 按住设备上的“FORCE RECOVERY” 按钮5秒
- 同时按下设备上的“POWER”按钮3秒,然后松开电源按钮
- 松开“FORCE RECOVERY” 按钮
2.2 设备上电情况下
- 按住设备上的“FORCE RECOVERY” 按钮5秒
- 同时按下设备上的“RESET”按钮3秒,然后松开电源按钮
- 松开“FORCE RECOVERY” 按钮
使用lsusb命令查看,如果显示下图内容表示已经进入恢复模式:
3. 调试串口和刷机下载接口
左图是刷机下载接口,右图是调试串口。