【NVIDIA】Jetson AGX Orin内核、设备树更新指南

博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持!
博主链接

本人就职于国际知名终端厂商,负责modem芯片研发。
在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。


博客内容主要围绕:
       5G/6G协议讲解
       算力网络讲解(云计算,边缘计算,端计算)
       高级C语言讲解
       Rust语言讲解



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目录下。


三、编译内核

  1. 安装基础软件包:
$ sudo apt install build-essential bc flex bison libncurses-dev libssl-dev
  1. 配置交叉编译环境
$ export CROSS_COMPILE_AARCH64_PATH=$HOME/l4t-gcc
$ export CROSS_COMPILE_AARCH64=$HOME/l4t-gcc/bin/aarch64-buildroot-linux-gnu-
  1. 创建内核编译文件的保存目录:
$ mkdir $HOME/kernel_output
  1. 运行下面的命令开始编译内核
$ ./nvbuild.sh -o $HOME/kernel_output

四、编译NVIDIA驱动

  1. 从2.2节解压的public_sources.tbz2中找到nvidia_kernel_display_driver_source.tbz2压缩包,并解压缩,目录结构如下图所示:
    在这里插入图片描述
  2. 设置环境变量:
$ export CROSS_COMPILE_AARCH64=$HOME/l4t-gcc/bin/aarch64-buildroot-linux-gnu-
$ export LOCALVERSION="-tegra"
  1. 进入解压缩后的文件夹,并执行下面的命令:
$ 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

  1. 访问Jetson Linux home page,下载rootfs压缩包,如下图所示,然后解压缩到\<path-to>/Linux_for_Tegra/rootfs(注意需要使sudo进行解压缩)

在这里插入图片描述

  1. 执行下面的命令安装NVIDIA扩展bin文件:
$ sudo ./apply_binaries.sh
  1. 创建一个用于x,密码为1,并设置自动登录(这一步是避免刷机后没有图新界面需要通过串口创建用户时的不稳定,这里的用户名和密码需要改成您自己的):
$ sudo ./tools/l4t_create_default_user.sh -u x -p 1 -a

5.1.3 将编译的产物拷贝到特定的位置

  1. 执行下面的命令,拷贝编译内核的产物:
$ 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
  1. 在 $HOME/kernel_output 目录下执行:
$ sudo make ARCH=arm64 O=$HOME/kernel_output modules_install INSTALL_MOD_PATH=<path-to>/Linux_for_Tegra/rootfs/
  1. 执行下面的命令,拷贝编译NVIDIA驱动的产物(nvidia-drm.konvidia.konvidia-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 开始刷机

  1. 按照附录-2进入恢复模式
  2. 执行下面的命令:
$ sudo ./flash.sh jetson-agx-orin-devkit internal
  1. 【可选】刷机后第一次开机,如果没有图形界面,需要通过串口输入
$ sudo depmod -a

然后重新启动Jetson,图形界面就回来了。

5.2 只更新内核和设备树(非刷机方式)

这个方法是我自己尝试的,目前没有发现问题

5.2.1 备份并更新内核

  1. 修改jetson板块中的/boot/extlinux/extlinux.conf文件,备份现在使用的内核,修改后的文件内容如下所示:
TIMEOUT 100
DEFAULT primary

MENU TITLE L4T boot options

LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image
      FDT /boot/dtb/kernel_tegra234-p3701-0000-p3737-0000.dtb
      INITRD /boot/initrd
      APPEND ${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 backup
      MENU LABEL primary kernel
      LINUX /boot/Image.backup
      FDT /boot/dtb/kernel_tegra234-p3701-0000-p3737-0000.dtb
      INITRD /boot/initrd
      APPEND ${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

  1. 将原始的内核镜像进行备份:
$ sudo cp /boot/Image /boot/Image.backup
  1. 通过scp命令将新内核拷贝到Jetson的/boot/Image
  2. 创建一个文件夹,例如
$ mkdir <path-to>/manual_update_kernel
$ sudo make ARCH=arm64 O=$HOME/kernel_output modules_install INSTALL_MOD_PATH=<path-to>/manual_update_kernel
  1. 将第四节编译的NVIDIA驱动,拷贝到manual_update_kernel的对应文件夹中。将nvgpu.ko也拷贝到对应的位置(参见5.1.3-1)
  2. manual_update_kernel/lib/modules下的文件打包,拷贝到jetson板卡后,替换对应位置的文件夹(/lib/modules/$(uname -r)
  3. 重启系统,在重启过程中会要求用户选择一个内核镜像。选择0就是新的内核镜像,1是备份内核镜像
  4. 执行下面的命令,并重启jetson
$ sudo depmod -a

5.2.2 备份并更新设备树文件

  1. 修改完设备树文件之后,重新编译内核,编译完成后会在$HOME/kernel_output/arch/arm64/boot/dts/nvidia目录下生成一个tegra234-p3701-0000-p3737-0000.dtb文件
  2. 将上述文件拷贝到Jetson板卡的/boot/dtb目录下
  3. 修改extlinux.conf文件中的FDT参数的值,使其指向正确的设备树文件

5.3 使用flash.sh脚本更新内核和设备树

  1. 可以通过下面的命令更新分区中的内核和设备树
$ 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. 调试串口和刷机下载接口

在这里插入图片描述
左图是刷机下载接口,右图是调试串口。



在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_31985307/article/details/131499050