设置您的文件系统
NVIDIA® Jetson™ Linux 需要一个根文件系统。您必须创建一个 Linux 主机系统并将其复制到您的参考板。
示例根文件系统
NVIDIA Jetson Linux 驱动程序包 (L4T) 附带一个为 NVIDIA Jetson 开发者套件预构建的示例根文件系统。
NVIDIA 提供了一个工具来生成根文件系统。要使用该工具,请导航到提取的 NVIDIA 驱动程序包的 tools/samplefs 目录
$ cd <your_L4T_root>/Linux_for_Tegra/tools/samplefs
执行脚本 nv_build_samplefs.sh
$ sudo ./nv_build_samplefs.sh --abi aarch64 --distro ubuntu --version bionic
要查看参数的解释,请单独输入脚本名称。(您无需使用 sudo。) 但是,由于该命令的使用方式与所示完全相同,因此您无需理解参数即可使用它。
注意 | 此脚本下载基本镜像,提取根文件系统,下载并安装所有必需的软件包,并将根文件系统目录压缩为 tarball。根据您主机机器的互联网速度,这可能需要几个小时才能运行。 |
设置根文件系统
在启动目标板之前,配置根文件系统 (rootfs) 以
• 设置 rootfs
• 将其复制到设备上的 rootfs
步骤 1:设置根文件系统
此过程使用 NVIDIA 提供的示例文件系统作为基础。如果您希望使用自己的文件系统,请设置 LDK_ROOTFS_DIR 环境变量以指向您的 rootfs 的位置,并跳过设置根文件系统的步骤。
要设置 rootfs
1. 将以下文件下载到您的主目录
Tegra-Linux-Sample-Root-Filesystem_<release_type>.tbz2
此文件包含 NVIDIA 提供的示例根文件系统。
2. 按如下方式提取压缩文件
• 导航到提取的 NVIDIA 驱动程序包的 rootfs 目录。
$ cd <your_L4T_root>/Linux_for_Tegra/rootfs
其中 <your_L4T_root> 是您的 L4T 根目录,假定为您的主目录 (~)。
• 将示例文件系统提取到 rootfs 目录。
$ sudo tar -jxpf ../../Tegra-Linux-Sample-Root-Filesystem_<release_type>.tbz2
3. 运行 apply_binaries.sh 脚本以将 NVIDIA 用户空间库复制到目标文件系统。
$ cd ..
$ sudo ./apply_binaries.sh
4. 如果您使用不同的 rootfs,或者如果您已经配置了您的 rootfs,请设置 LDK_ROOTFS_DIR 环境变量以指向您的 rootfs。然后运行如上所示的脚本,将二进制文件复制到您的目标文件系统。
如果 apply_binaries.sh 脚本正确安装了二进制文件,则脚本输出的最后一条消息是“Success!”。
您现在已完成根文件系统的设置。继续将 rootfs 刷写到目标 SoC 设备。
步骤 2:将 rootfs 复制到 Jetson 设备
您必须用于复制 rootfs 的过程取决于您要存储它的存储类型
要使用刷写工具在设备上设置根文件系统,请参阅主题
刷写和启动目标设备。
如果您更喜欢自己设置根文件系统而不是使用刷写工具,请使用以下步骤。
将文件系统复制到外部存储设备
1. 将您的 rootfs 设备插入主机系统。
2. 如果您的设备未格式化为 Ext4,请输入以下命令将其格式化为 Ext4 文件系统
$ sudo mkfs.ext4 /dev/sd<port><device_number>
其中
• <port> 是您的设备挂载到的端口。
• <device_number> 是连接到端口的设备的设备号。您可以使用 dmesg 命令来确定端口。
3. 如果需要,使用以下命令挂载您的设备
$ sudo mount /dev/sdX1 <mntpoint>
其中 <mntpoint> 是主机系统上您的 rootfs 设备的挂载点。
4. 复制文件系统。如果设置了 LDK_ROOTFS_DIR,请执行以下命令
$ cd ${LDK_ROOTFS_DIR}
$ sudo cp –a * <mntpoint> && sync
5. 如果未设置,请复制发行版中包含的 rootfs 目录,方法是执行以下命令
$ cd <your_L4T_root>/Linux_for_Tegra/rootfs
$ sudo cp –a * <mntpoint> && sync
6. 将内容复制到外部磁盘或设备后,卸载磁盘并将其连接到目标 SoC 设备。
根文件系统冗余
NVIDIA® Jetson™ Linux 在 NVIDIA Jetson Xavier™ NX 系列、Jetson AGX Xavier™ 系列和 Jetson TX2 系列上提供对根文件系统冗余(“rootfs 冗余”)的完全支持。它使用两个根文件系统,一个指定为 rootfs A 并存储在通常的文件系统分区 APP 中,另一个指定为 rootfs B 并存储在新分区 APP_b 中,该分区位于磁盘上的 APP 之后。
Rootfs 冗余支持两个文件系统的独立创建和更新、切换和故障转移。
注意 | Rootfs 冗余是一项高级功能,适用于有能力创建自定义 rootfs 镜像的客户。 |
分区名称 APP 和 APP_b 不得更改。
Rootfs 选择
L4T 提供了一个选项来关联引导加载程序 A/B 和 rootfs A/B。如果启用 rootfs A/B,则默认情况下引导加载程序 A/B 将与 rootfs A/B 关联。
有关如何启用和禁用此选项的信息,请参阅
自定义 SMD 分区镜像。
在统一引导加载程序和 Rootfs A/B 禁用的情况下进行 Rootfs 选择
当禁用“统一引导加载程序 A/B 和 rootfs A/B”选项时,引导加载程序 A/B 和 rootfs A/B 插槽选择彼此独立。引导加载程序和 Rootfs 有四种可能的组合
每个 rootfs 都有几个属性
每个 rootfs 在冗余文件系统架构中占用一个 插槽:“插槽 A”或“插槽 B”。
当使用 rootfs 冗余时,kernel 和 kernel-dtb 分区属于用户空间,而不是引导加载程序。因此,它们属于 rootfs 插槽,并由其 rootfs 插槽而不是其引导加载程序插槽选择。
活动 rootfs 插槽是下次启动操作将尝试从中启动的插槽。活动 rootfs 插槽(Linux 使用的 rootfs 的插槽)不一定是引导加载程序活动插槽(Linux 从其引导加载程序启动的插槽)。
当前 rootfs 插槽是系统从中启动并当前正在使用的插槽。另一个 rootfs 插槽称为 未使用的 rootfs 插槽。系统可能会在更新过程中或在当前 rootfs 在启动时或启动后立即重复失败时交换当前和未使用 rootfs 插槽的角色。当前 rootfs 插槽与引导加载程序当前插槽无关。
rootfs 插槽的 状态属性指示 rootfs 是否包含可用于启动设备的有效系统镜像。当系统运行时,当前 rootfs 插槽的状态必然是可启动的。未使用的 rootfs 插槽可能具有系统较旧、相同或较新的版本,并且可能是也可能不是可启动的。“状态”属性由 CBoot 和 更新引擎 (UE) 管理,后者管理更新 rootfs 分区。
更新模式属性指示系统已尝试在此 rootfs 上运行 OTA 更新。此属性也由 UE 处理。
如果当前 rootfs 在指定的次数内启动失败,CBoot 将重置其状态属性并切换当前和未使用 rootfs 插槽的角色。如果两个根文件系统都不可启动,则设备尝试从恢复内核镜像启动。
默认情况下,CBoot 尝试启动 rootfs 三次。尝试次数是可配置的;请参阅
自定义 SMD 分区镜像。
在统一引导加载程序和 Rootfs A/B 启用的情况下进行 Rootfs 选择
当启用“统一引导加载程序 A/B 和 rootfs A/B”选项时,引导加载程序 A/B 和 rootfs A/B 将一起配置。引导加载程序插槽和 rootfs 插槽一起切换,以便引导加载程序 A 仅与 rootfs A 一起启动,而引导加载程序 B 仅与 rootfs B 一起启动。引导加载程序和 rootfs 有两种组合
如何创建冗余根文件系统
L4T 提供了一个简单的刷写命令,用于创建 rootfs 冗余并在目标板上刷写。您可以在刷写之前进行一些自定义设置。
在创建文件系统之前,找到您的 Jetson 设备的布局文件,并将它们与相应的非冗余系统的布局文件并排检查。了解差异对于您理解文件系统冗余的工作原理非常重要。
布局文件是一个 XML 文件,描述了 L4T 系统的分区布局。一个或多个特定的布局文件描述了每个 Jetson 平台的分区布局。以下列表命名了各种平台上冗余文件系统的布局文件。在每种情况下,相应的非冗余布局文件都具有相同的名称,但没有文件名后缀 _rootfs_ab
• 对于带有 SD 内存的 Jetson Xavier NX 开发模块
Linux_for_tegra/bootloader/t186ref/cfg/flash_l4t_t194_spi_sd_p3668_rootfs_ab.xml
• 对于带有 eMMC 的 Jetson Xavier NX 生产模块
Linux_for_Tegra/bootloader/t186ref/cfg/flash_l4t_t194_spi_emmc_p3668_rootfs_ab.xml
• 对于 Jetson AGX Xavier 系列
Linux_for_Tegra/bootloader/t186ref/cfg/flash_t194_sdmmc_rootfs_ab.xml
• 对于 Jetson TX2 系列
Linux_for_Tegra/bootloader/t186ref/cfg/flash_l4t_t186_rootfs_ab.xml
要使用冗余根文件系统刷写目标板
转到 Linux_for_Tegra 目录并输入命令
$ sudo ROOTFS_AB=1 ./flash.sh [options] <target_board> <rootdev>
其中
• ROOTFS_AB=1 启用 rootfs 冗余。
• <target_board> 指示设备类型
对于 Jetson Xavier NX 系列:jetson-xavier-nx-devkit-emmc 或 jetson-xavier-nx-devkit
对于 Jetson AGX Xavier 系列:jetson-agx-xavier-devkit
对于 Jetson TX2 系列:jetson-tx2-devkit
• <rootdev> 指定根文件系统的位置。
例如
$ sudo ROOTFS_AB=1 ./flash.sh jetson-tx2-devkit mmcblk0p1
要在外部存储设备上刷写冗余根文件系统,请参阅 Linux_for_Tegra/tools/kernel_flash/README.txt 中的工作流程 #5。
要自定义 rootfs 大小
当使用 rootfs 冗余时,每个 rootfs 分区(APP 和 APP_b)的大小是未使用 rootfs 冗余时 rootfs 大小的一半。该大小在目标板的配置文件中由 ROOTFSSIZE 指定。
您可以通过在刷写目标之前更改 ROOTFSSIZE 的值来更改分配给根文件系统的空间量。
您必须更改以自定义 rootfs 大小的配置文件是
• 对于 Jetson Xavier NX 系列:Linux_for_Tegra/p3668.conf.common
• 对于 Jetson AGX Xavier 系列:Linux_for_Tegra/p2972-0000.conf.common
• 对于 Jetson TX2 系列:Linux_for_Tegra/P2771-0000.conf.common
例如,要更改 Jetson TX2 的 rootfs 大小,请编辑 p2771-0000.conf.common
if [ "${ROOTFS_AB}" == 1 ]; then
rootfs_ab=1
EMMC_CFG=flash_l4t_t186_rootfs_ab.xml;
ROOTFSSIZE=14GiB;
fi;
要自定义 SMD 分区镜像
SMD 分区保存有关插槽状态的信息。具有冗余文件系统的设备有两个分区,SMD 用于插槽 A,SMD_b 用于插槽 B。您可以在刷写目标之前自定义 SMD 分区。
注意 | 一些 L4T 文档将 SMD 和 SMD_b 分区一起称为“SMD 分区”。在阅读 REAME 文件和其他文档时,请记住这一点。 |
Rootfs 冗余要求 SMD 分区正常工作。SMD 分区镜像存储在文件 slot_metadata.bin.rootfsAB 中,该文件由脚本 nv_smd_generator 从 l4t_smd_info.rootfs_AB.cfg 生成。
默认的 l4t_smd_info.rootfs_AB.cfg 文件如下所示
< VERSION 5 >
# 设置最大 rootfs 插槽重试计数
# 请确保在插槽信息配置之前设置此字段
# 有效设置为 1 到 3
< MAX_ROOTFS_AB_RETRY_COUNT 3 >
#
# 配置 1:禁用 A/B 支持(通过删除注释 ##)
#
# 插槽信息顺序很重要!
# <priority> <suffix> <retry_count> <boot_successful>
##15 _a 7 1
#
# 配置 2:启用 rootfs A/B 支持(默认)
#
< REDUNDANCY_ENABLE 1 >
< ROOTFS_AB 1 >
# 要启用 rootfs 自动同步,请使用 < RF_AUTOSYNC_ENABLE 1 >
# 此选项必须在 "< ROOTFS_AB 1 >" 之后定义
##< RF_AUTOSYNC_ENABLE 1 >
# 选择 rootfs A 作为活动 rootfs 插槽
< ROOTFS_ACTIVE_A 1 >
##< ROOTFS_ACTIVE_B 1 >
# 启用/禁用统一引导加载程序 AB 和 rootfs AB
# 设置 1 以启用,设置 0 以禁用。默认为启用
# 此选项必须在 "< ROOTFS_AB 1 >" 之后定义
# 当 < ROOTFS_BL_UNIFIED_AB 1 > 设置时,
# BL 和 RF 的自动同步均被禁用。
< ROOTFS_BL_UNIFIED_AB 1 >
# 要禁用引导加载程序自动同步,请使用 < BL_AUTOSYNC_DISABLE 1 >,默认情况下禁用。
# REDUNDANCY_ENABLE 或 REDUNDANCY_USER 必须在之前定义
# BL_AUTOSYNC_DISABLE !
< BL_AUTOSYNC_DISABLE 1 >
# 插槽信息顺序很重要!
# <priority> <suffix> <retry_count> <boot_successful>
15 _a 7 1
14 _b 7 1
< MAX_ROOTFS_AB_RETRY_COUNT 3 >(上面突出显示)设置最大 rootfs 插槽尝试计数。这是 CBoot 在切换当前和未使用 rootfs 插槽的角色之前尝试启动 rootfs 的次数。设置范围为 1 到 3;默认为 3。
< ROOTFS_AB 1 >(上面也突出显示)启用 rootfs 冗余。要禁用 rootfs 冗余,请将此行更改为 < ROOTFS_AB 0 >。
< ROOTFS_ACTIVE_A 1 >(也突出显示)使 rootfs 插槽 A 成为默认活动 rootfs 插槽。要使 rootfs 插槽 B 成为默认活动 rootfs 插槽,请将此行更改为 < ROOTFS_ACTIVE_B 1 >。
< ROOTFS_BL_UNIFIED_AB 1 >(也突出显示)启用或禁用统一引导加载程序 A/B 和 rootfs A/B。要禁用统一引导加载程序 A/B 和 rootfs A/B,请将此行设置为 < ROOTFS_BL_UNIFIED_AB 0 >。默认设置为 1。当设置 ROOTFS_BL_UNIFIED_AB 时,引导加载程序和根文件系统的自动同步均被禁用。
如果 rootfs A/B 和统一引导加载程序 A/B 都要启用,则 < ROOTFS_ACTIVE_A 1 > 必须在 < ROOTFS_BL_UNIFIED_AB 1 > 之前位于 .cfg 文件中。
< BL_AUTOSYNC_DISABLE 1 >(也突出显示)禁用引导加载程序自动同步。要启用引导加载程序自动同步,请将此行更改为 < BL_AUTOSYNC_DISABLE 0 >。请注意,1 禁用引导加载程序自动同步,而 0 启用它。默认值为 1。
要自定义 SMD 分区
1. 修改 l4t_smd_info.rootfs_AB.cfg。
2. 在 X86 主机系统上运行 nv_smd_generator 以生成新的 SMD 镜像 slot_metadata.bin.rootfsAB。
C:\...> nv_smd_generator <config_file> <output_file>
其中
• <config_file> 是 SMD 配置文件。
• <output_file> 是输出 SMD 镜像文件的名称。
例如
C:\...> nv_smd_generator l4t_smd_info.rootfs_AB.cfg slot_metadata.bin.rootfsAB
3. 将 slot_metadata.bin.rootfsAB 复制到主机。
4. 将 SMD 分区刷写到目标设备
使用 nvbootctrl 管理 Rootfs 插槽
nvbootctrl 工具可以帮助您测试和开发一对冗余文件系统。您可以使用它来显示两个根文件系统的状态,或在插槽 A 和插槽 B 之间更改活动 rootfs 插槽。
运行 nvbootctrl 工具的 shell 命令是
$ sudo nvbootctrl [ -t <target>] <command>
其中
• <target> 是目标的类型。它可以是 bootloader 或 rootfs。默认值(当未使用 -t 选项时生效)为 bootloader。
• <command> 是此表中显示的工具的命令之一
命令 | 描述 |
---|
get-number-slots | 打印插槽数。 |
get-current-slot | 打印当前正在运行的插槽的索引。 |
mark-boot-successful | 将当前插槽标记为“良好”。 |
set-active-boot-slot <slot> | 使下次启动加载并执行指定的插槽。 |
set-slot-as-unbootable <slot> | 将 <slot> 标记为无效。 |
is-slot-bootable <slot> | 如果 <slot> 可启动,则返回 0,否则返回非零值。 |
is-slot-marked-successful <slot> | 仅当 <slot> 标记为“良好”时返回 0,否则返回非零值。 |
get-suffix <slot> | 打印 <slot> 的后缀。 |
dump-slots-info | 打印有关插槽的信息。 |
is-autosync-enabled | 打印自动同步的状态(已启用或已禁用)。仅适用于引导加载程序。 |
toggle-autosync | 切换自动同步的启用状态。仅适用于引导加载程序。 |
is-unified-enabled | 返回 • 0 如果统一 A/B 和统一 A/B 都已启用 • 69 如果统一 A/B 和 rootfs A/B 都已禁用 • 70 如果 rootfs A/B 已启用且统一 A/B 已禁用 (第四种组合,rootfs A/B 禁用且统一 A/B 启用,是不可能的。) |
<slot> 是一个从零开始的插槽号:0 代表插槽 A,1 代表插槽 B。 |
注意 | 当“统一引导加载程序 A/B 和 rootfs A/B”启用时,不支持命令 sudo nvbootctrl ‑t rootfs <command>,并且 nvbootctrl 会打印警告消息“sudo nvbootctrl <command> 指示引导加载程序和 rootfs 信息。” |
要转储根文件系统插槽 A 和插槽 B 信息
• 输入命令
$ sudo nvbootctrl -t rootfs dump-slots-info
要在根文件系统插槽 A 和插槽 B 之间切换
• 输入命令
$ sudo nvbootctrl -t rootfs set-active-boot-slot <slot>
其中 <slot> 是设备下次重启后激活的插槽。
故障转移 Rootfs 插槽切换
如果具有 rootfs 冗余的 Jetson 设备在指定的连续次数内启动失败(请参阅
自定义 SMD 分区镜像),它将故障转移到未使用的 rootfs 插槽。也就是说,它使未使用的 rootfs 插槽成为活动 rootfs 插槽,反之亦然,然后尝试再次启动。
如果两个 rootfs 插槽都不可启动,则设备将启动到恢复内核镜像。
后台服务 l4t-rootfs-validation-config.service 检查根文件系统启动是否成功。此服务调用客户提供的脚本 /usr/sbin/user_rootfs_validation.sh,以根据用户定义的标准验证 rootfs。默认情况下,未定义此脚本。
注意 | 如果 user_rootfs_validation.sh 返回非零退出代码,则服务尝试重新启动设备。如果返回 0 或未定义,则服务不再执行任何操作,而是启动 nv_update_verifier 服务以验证引导加载程序和 rootfs 上的 A/B 更新。 |
将 UUID 用于根文件系统分区 APP 和 APP_b
当启用 rootfs 冗余时,始终使用分区 UUID 而不是设备名称来标识 APP 和 APP_b 分区。分区 UUID 引用的形式为 <xxxx>(UUID),其中 <xxxx> 是分区的 UUID。
在您使用两个根文件系统刷写 Jetson 设备后,用于
APP 分区的 UUID 存储在
bootloader/l4t-rootfs-uuid.txt 中,用于
APP_b 分区的 UUID 存储在
bootloader/l4t-rootfs-uuid.txt_b 中。您可以通过在执行刷写命令之前将 UUID 写入这些文件来指定您自己的 UUID,如
如何创建和刷写根文件系统 A 和 B 中所示。
启用 Rootfs 冗余的空中更新
Jetson Linux 支持启用 rootfs 冗余的基于镜像的空中 (OTA) 更新。有关更新过程的更多信息,请参阅主题
空中更新中的
使用基于镜像的空中更新更新 Jetson Linux。
当启用“统一引导加载程序 A/B 和 rootfs A/B”选项时,Jetpack Debian 软件包 over-the-air update 将被禁用。
对于使用 rootfs 冗余的系统,不建议执行带有 Debian 软件包的 OTA 更新,尽管当禁用“统一引导加载程序 A/B 和 rootfs A/B”选项时,这是可能的。这是因为 Debian 软件包仅更新当前 rootfs 插槽中的文件。系统在重新启动后不会切换活动 rootfs 插槽。