📺 B站:博主个人介绍
📘 博主书籍-京东购买链接*:Yocto项目实战教程
📘 加博主微信,进技术交流群: jerrydev
Jetson Image-based OTA:DevKit 从零跑通官方 Demo 实操指南(R36.4.x)
目标:用 NVIDIA 官方提供的 OTA tools + payload,在一块 Jetson DevKit 上完整跑通一次 image-based OTA(Host 生成 payload → 设备侧触发 → reboot 进入 recovery kernel → 更新完成)。
说明:本文重点是“跑通官方 demo”。你会看到 服务器端只在产品化时才必需;做 demo 可以先用
scp/USB/本地 HTTP代替“服务器下载”。

0. 先把话说清楚:你要跑通的“Image-based OTA demo”到底是什么
Jetson 的 image-based OTA 不是 apt upgrade 那种“装几个软件包”式升级。
它的本质是:
- 在 Host 上把目标版本 BSP 需要更新的分区镜像(bootloader/kernel/rootfs 等)打包成一个
ota_payload_package.tar.gz。 - 在目标设备上用
nv_ota_start.sh触发升级。 - 设备重启后进入 recovery kernel,由 recovery 环境完成真正的分区写入与切换。
你最终得到的不是“升级了某个包”,而是“设备被升级到一套一致的 BSP 版本快照”。
这也是 image-based OTA 的工程价值:一致性更强、可控性更强、适合 BSP/分区级升级。
1. 你现在找不到 l4t_generate_ota_package.sh 的原因(最常见坑)
很多人第一次按目录去找脚本都会懵:
- 你在
Linux_for_Tegra/里能看到tools/,但找不到tools/ota_tools/version_upgrade/l4t_generate_ota_package.sh。
这是正常的:
✅ l4t_generate_ota_package.sh 并不一定在“裸 Driver Package”里。它来自 ota_tools_<rel>_aarch64.tbz2 这个 OTA tools 包。
也就是说:
- 你必须先下载
ota_tools_<rel>_aarch64.tbz2 - 然后解压到
Linux_for_Tegra的上一级目录(让它把tools/ota_tools/...放进 BSP 目录)
解压完成后脚本才会出现。
快速自检:
# 在你的 Linux_for_Tegra 目录执行:
ls tools/ota_tools/version_upgrade/l4t_generate_ota_package.sh
# 如果提示不存在,说明 OTA tools 还没解压到位
2. Demo 跑通一次 OTA,你需要准备哪些东西
2.1 你至少需要“两份 BSP”
为了生成“从旧版升级到新版”的 OTA payload,你至少需要:
- BASE_BSP:设备当前运行的旧版本 BSP(base release)
- TARGET_BSP:你想升级到的新版本 BSP(target release)
初学者最推荐的 demo:用 同一大版本线内的 point release(例如 R36.4.3 → R36.4.4)来跑通流程,变量更少,排错更轻松。
2.2 你需要的两个交付物(最终要放到设备侧)
ota_tools_<rel>_aarch64.tbz2(工具包)ota_payload_package.tar.gz(分区镜像 payload)
做 demo 时:你可以先把它们拷到板子上。
产品化时:它们通常会放到你的 OTA server,由设备端 OTA client 下载。
2.3 设备侧空间要求
ota_payload_package.tar.gz 解压 + 处理需要设备侧有足够空闲空间。
经验上你至少要准备 7GB 以上(默认 rootfs 的 payload 本身常见在数 GB 级别,具体取决于你 rootfs 大小)。
2.4 你需要知道设备的 rootfs 在哪里(eMMC 还是 NVMe)
在目标设备上运行:
findmnt /
lsblk
看到 / 挂载在 /dev/nvme0n1pX,说明你是 NVMe rootfs;
看到 /dev/mmcblk0pX,说明你是 eMMC/SD rootfs。
这会影响你后面生成 payload 时是否需要 --external-device、-S 等参数。
3. 学习路线与方法(从“跑通”到“能做产品”)
这一章是本文的“升级版核心”。很多初学者会卡在两个点:
- 只会照命令跑一次,但不知道哪些信息是关键证据、哪些变量会影响结果。
- 不知道下一步怎么学:NVMe、A/B、UEFI Secure Boot、Disk Encryption、数据保留、自定义任务链到底怎么插进整体框架。
下面给你一套可复用的学习方法:
3.1 三层学习目标(建议按顺序完成)
第 1 层:跑通链路(Demo 级)
-
目标:Host 能生成 payload;Device 能触发并完成升级;能验证版本变化。
-
输出物:
- Host 侧:payload 文件路径与大小(
ota_payload_package.tar.gz) - Device 侧:升级前后
/etc/nv_tegra_release、uname -a、日志(成功/失败)
- Host 侧:payload 文件路径与大小(
第 2 层:可控与可观测(工程级)
-
目标:知道“升级过程在哪执行”“失败在哪里看”“如何复现”。
-
输出物:
- 关键日志打包与归档策略
- 故障注入复现记录(比如中途重启/断电一次)
- 关键检查点(checkpoints)列表
第 3 层:产品化框架(产品级)
-
目标:把 OTA 从“手动脚本”变成“守护进程 + manifest + 安全校验 + 上报 + 灰度”。
-
输出物:
- OTA client/service 的状态机
- manifest 设计(版本、兼容性、hash/signature、策略)
- server 端目录结构与访问鉴权方案
3.2 四个视角帮助你“理解而不是背命令”
你学 OTA 时,建议同时从四个视角看同一个流程:
- 数据流(Data Flow):payload 是怎么生成、怎么传输、怎么落盘、怎么被消费的?
- 控制流(Control Flow):谁发起、谁切换到 recovery、谁真正写分区?
- 一致性(Consistency):哪些分区必须一起升级?哪些场景可以只更 bootloader / 只更 rootfs?
- 恢复策略(Recovery):失败后在哪里停住?如何重试?如何回滚?
只要这四个视角建立起来,后面加 Secure Boot / Encryption / NVMe / A/B 只是“多一些参数与约束”,不会把你打回原点。
3.3 学习方法:用“证据驱动”的笔记法
我建议你每跑一次 OTA,都固定保存下面这些“证据”,这样你会越来越快:
-
设备升级前后:
cat /etc/nv_tegra_releaseuname -alsblk+findmnt /(确认 rootfs 载体)
-
Host 侧:
- 生成命令(完整参数)
- payload 的
sha256sum与文件大小 - 使用的 BASE_BSP/TARGET_BSP 路径与版本
-
Device 侧日志:
/ota_logs/目录打包(失败时一定要留)- 如果启用
RESERVE_LOGS=true,保留/last_ota_update_log
这样做的好处:你以后遇到任何升级异常,不是“感觉不对”,而是“有证据能定位”。
3.4 学习路线建议(按模块递进)
建议你不要一上来就把所有高级特性叠加。最稳的顺序是:
- 最小 Demo:内部存储 rootfs + 无 secure boot + 无加密(本文主流程)
- 可观测性增强:保留成功日志 + 故障注入一次
- NVMe rootfs:
--external-device与-S - 数据保留:
nv_ota_preserve_data.sh+ 文件清单 - 自定义任务链:
nv_ota_customer.conf的OTA_TASKS - UEFI Secure Boot:
--uefi-keys/UUID/overlay 包 - Disk Encryption:
ROOTFS_ENC=1、EKS/EKB 一致性
每加一个模块,你只需要回答一个问题:
- 它引入了哪些新输入(参数/文件/密钥/UUID)?
- 它改变了流程中的哪一步?(生成 payload / 触发 / recovery 任务链 / 分区写入)
4. 全局流程框架图(控制流 + 数据流)
下面这张图建议你反复看。它把“demo”和“产品化”放在同一框架里:
┌────────────────────────────┐
│ Host │
│ (build / generate payload)│
└──────────────┬─────────────┘
│
│ 生成
│ - ota_payload_package.tar.gz
│ - (可选) UEFI overlay 等
▼
┌───────────────────────────┐
│ Artifacts/Repo │
│ (文件落地位置/制品库) │
└──────────────┬────────────┘
│
demo: scp/USB │ product: OTA Server/CDN
▼
┌────────────────────────────────────┐
│ Device │
│ OTA client/service(你自己实现) │
│ - 下载 tools/payload │
│ - 校验(hash/sign/encrypt) │
│ - 调用 nv_ota_start.sh │
└──────────────┬─────────────────────┘
│
│ 触发后重启
▼
┌────────────────────────────────────┐
│ Recovery Kernel │
│ - nv_ota_run_tasks.sh 任务链 │
│ - 写分区/切换/验证/失败处理 │
│ - 产生 /ota_logs/ │
└──────────────┬─────────────────────┘
│
│ 完成后重启
▼
┌────────────────────────────────────┐
│ Updated System │
│ - 版本验证 │
│ - 上报结果(成功/失败/日志) │
└────────────────────────────────────┘
这张图里你要记住两句话:
- 真正写分区的工作是在 Recovery Kernel 里完成的。
- 服务器端与 OTA client 是“产品化的必需品”,但 Demo 可以先不用。
5. 一张流程图:把整个 demo 拆成 8 个动作
Host 端
(1) 准备 BASE_BSP / TARGET_BSP
(2) TARGET_BSP: 解压 sample rootfs + apply_binaries
(3) 解压 ota_tools_<rel>_aarch64.tbz2 到 TARGET_BSP 上一级
(4) 运行 l4t_generate_ota_package.sh 生成 ota_payload_package.tar.gz
传输
(5) 把 ota_tools_<rel>_aarch64.tbz2 + ota_payload_package.tar.gz 拷到设备
Device 端
(6) 解压 ota_tools 到 WORKDIR
(7) 把 payload 放到 /ota/,执行 nv_ota_start.sh
(8) reboot → recovery kernel 自动执行 OTA → 回到系统验证
4. Host 端:生成 OTA payload(一步一步照着做)
下面我用一个“最接近官方文档的写法”来讲。你可以把路径换成你自己的目录。
4.1 准备目录与变量
假设你的工作目录结构像这样:
~/ota_demo/
├── base_R36.4.3/Linux_for_Tegra/
├── target_R36.4.4/Linux_for_Tegra/
├── ota_tools_R36.4.4_aarch64.tbz2
└── (样例 rootfs tbz2)
设置环境变量:
export BASE_BSP=~/ota_demo/base_R36.4.3/Linux_for_Tegra
export TARGET_BSP=~/ota_demo/target_R36.4.4/Linux_for_Tegra
注意:
BASE_BSP/TARGET_BSP要指向 Linux_for_Tegra 目录本身。
4.2 在 TARGET_BSP 准备 rootfs(sample rootfs + apply_binaries)
进入目标 BSP:
cd $TARGET_BSP
# 进入 rootfs 目录,把 sample rootfs 解压进去
cd rootfs
sudo tar xpf ../../Tegra_Linux_Sample-Root-Filesystem_<rel>_aarch64.tbz2
cd ..
# 把 NVIDIA 的二进制组件合入 rootfs
sudo ./apply_binaries.sh
如果你已经用自己的 rootfs(定制过)替换了 sample rootfs,也可以,但初学 demo 强烈建议先用 sample rootfs 跑通。
4.3 解压 OTA tools:让脚本出现在 tools/ota_tools/...
这是你现在最可能缺的步骤。
在 Linux_for_Tegra 的上一级执行解压:
cd ${TARGET_BSP}/..
# tbz2 常见写法:-j 表示 bzip2
sudo tar xjpf ota_tools_<rel>_aarch64.tbz2
解压后你应该能看到:
ls ${TARGET_BSP}/tools/ota_tools/version_upgrade/l4t_generate_ota_package.sh
如果这一步仍然找不到,通常原因只有两类:
- 你解压的位置不对(没有解压到
${TARGET_BSP}/..) - 你下载的
ota_tools_<rel>_aarch64.tbz2与目标 BSP 版本不匹配
4.4 选择正确的 <target_board>(DevKit 最常用)
官方把不同设备映射到 target_board 名称(也就是你平时 flash.sh 用的那个板级名)。
常见 Orin 系列:
- Jetson AGX Orin DevKit:
jetson-agx-orin-devkit - Jetson AGX Orin Industrial:
jetson-agx-orin-devkit-industrial - Jetson Orin NX / Orin Nano(很多情况下都用):
jetson-orin-nano-devkit
你可以通过以下方式辅助确认:
# Linux_for_Tegra 下有大量 *.conf
ls *.conf
# 你也可以看你曾经 flash 时用的是哪一个
# 比如 jetson-orin-nano-devkit.conf / jetson-orin-nano-devkit-nvme.conf
4.5 运行 l4t_generate_ota_package.sh 生成 payload
进入目标 BSP 根目录:
cd $TARGET_BSP
生成命令结构是:
sudo -E ./tools/ota_tools/version_upgrade/l4t_generate_ota_package.sh \
[options] <target_board> <bsp_version>
<bsp_version>是“base BSP 的大版本线”,格式像R36-4、R35-5这种。- 如果你的 base 设备当前是 36.4.x,那么这里一般用
R36-4。
最小 demo(内部存储 rootfs,无加密、无 secure boot):
sudo -E ./tools/ota_tools/version_upgrade/l4t_generate_ota_package.sh \
jetson-orin-nano-devkit R36-4
说明:这个脚本默认会基于
Linux_for_Tegra/rootfs/生成 rootfs 镜像,再把需要更新的分区镜像都打进 payload。
生成结果在哪里?
通常会生成在:
${TARGET_BSP}/bootloader/<target_board>/ota_payload_package.tar.gz
你可以这样确认:
ls -lh ${TARGET_BSP}/bootloader/jetson-orin-nano-devkit/ota_payload_package.tar.gz
4.6(可选)如果你的 rootfs 在 NVMe:添加 --external-device 与 -S
如果你是 NVMe 启动/根文件系统在 NVMe,通常需要类似:
sudo -E ./tools/ota_tools/version_upgrade/l4t_generate_ota_package.sh \
--external-device nvme0n1 -S <rootfs_size> \
jetson-orin-nano-devkit R36-4
--external-device nvme0n1表示外置设备-S用于指定 rootfs 分区大小(具体取值与你的分区规划有关)
初学 demo:你可以先用“内部存储 rootfs”的设备跑通一次,再挑战 NVMe 场景。
5. 把文件拷到 DevKit(demo 不需要正式服务器)
你需要拷两个文件到板子上:
ota_tools_<rel>_aarch64.tbz2ota_payload_package.tar.gz
最常用做法:用 scp:
# Host 上执行
scp ota_tools_R36.4.4_aarch64.tbz2 ubuntu@<JETSON_IP>:~/
scp ${TARGET_BSP}/bootloader/jetson-orin-nano-devkit/ota_payload_package.tar.gz ubuntu@<JETSON_IP>:~/
也可以用 U 盘或局域网临时 HTTP。
再强调一次:跑 demo 不需要服务器。
服务器端是“产品化 OTA”(规模化分发、鉴权、安全、灰度)才必须的。
6. 设备侧:触发 OTA(最关键的 10 分钟)
6.1 安装依赖并检查空间
在 Jetson 上:
sudo apt-get update
sudo apt-get install -y efibootmgr nvme-cli
df -h /
确认 / 有足够空闲空间(建议 7GB+)。
6.2 准备 WORKDIR 并解压 OTA tools
mkdir -p ~/ota_work
export WORKDIR=~/ota_work
cd $WORKDIR
sudo tar xjpf ~/ota_tools_<rel>_aarch64.tbz2
解压后你应该能看到:
ls $WORKDIR/Linux_for_Tegra/tools/ota_tools/version_upgrade/nv_ota_start.sh
6.3 准备 /ota/ 并放入 payload
sudo mkdir -p /ota
sudo cp ~/ota_payload_package.tar.gz /ota/
如果你启用了 UEFI secure boot,并且生成了 overlay 包,也需要一并放进去:
# 仅当你确实启用 UEFI secure boot 时
sudo cp ~/uefi_secureboot_overlay_multi_specs.tar.gz /ota/
6.4 执行 nv_ota_start.sh 并 reboot
cd $WORKDIR/Linux_for_Tegra/tools/ota_tools/version_upgrade
# 触发 OTA 预处理
sudo ./nv_ota_start.sh /ota/ota_payload_package.tar.gz
# 没报错就重启
sudo reboot
重启后通常现象:
- 设备会进入 recovery kernel 环境
- 屏幕可能黑一段时间/或显示不同的启动过程(这取决于平台与配置)
- 更新完成后自动重启回系统
6.5 验证升级是否成功
回到系统后做三个验证:
- 查看 L4T 版本:
cat /etc/nv_tegra_release
- 查看内核版本:
uname -a
- 如果你启用了 A/B,可以看 slot 信息(不同版本工具略有差异):
# 可能存在:
nvbootctrl dump-slots-info || true
nvbootctrl get-current-slot || true
7. 你最可能遇到的 12 个问题(以及一眼能懂的处理方式)
Q1:Host 上找不到 l4t_generate_ota_package.sh
原因 99%:没解压 ota_tools 包到正确位置。
你需要在 ${TARGET_BSP}/.. 执行:
cd ${TARGET_BSP}/..
sudo tar xjpf ota_tools_<rel>_aarch64.tbz2
然后脚本才会出现在:
${TARGET_BSP}/tools/ota_tools/version_upgrade/l4t_generate_ota_package.sh
Q2:生成 payload 很慢,像“卡住”
l4t_generate_ota_package.sh 默认会生成多 spec 的 payload(覆盖多个设备/配置),这会显著拉长时间。
思路:
- 先确认你只需要某个 devkit 的 spec
- 按官方建议可以通过
ota_board_specs.conf注释掉不需要的 spec 来加速
Q3:设备侧报空间不足/解压失败
- 检查
df -h / - 清理无用文件、docker 镜像、旧日志
- 确保你把 payload 放在一个有足够空间的文件系统上
Q4:设备重启后进了 recovery shell 或更新失败
失败日志会在:
/ota_logs/
把日志打包出来最有效:
sudo tar czf ota_logs.tgz /ota_logs
Q5:成功了但日志没了
默认成功会自动删日志。
如果你想保留成功日志,需要在配置里打开 RESERVE_LOGS=true(属于 customization 话题,后面会提)。
Q6:我启用了 Secure Boot,OTA 后进 UEFI Shell
这通常说明:
- UEFI payload / 证书链 / overlay 包处理不完整
- 或者 boot 配置/UUID 不匹配
建议你先用“不启用 secure boot”的最小 demo 跑通,再逐层加 secure boot。
Q7:NVMe rootfs 升级不对/升级后找不到 rootfs
最常见原因:
- Host 端生成 payload 时没有带
--external-device nvme0n1与-S
先跑通 internal rootfs,再来 NVMe,会更顺。
Q8:想保留用户数据怎么办
官方提供了“APP 分区文件备份/恢复”脚本:
nv_ota_preserve_data.shota_backup_files_list.txt
你可以把要保留的路径列进去(相对根目录的写法)。
Q9:我用的是自定义 rootfs(不是 sample rootfs)
两条路:
- 简单路:先把你的 rootfs 直接放到
Linux_for_Tegra/rootfs/再生成 - 稍复杂:用
-o指定 rootfs updater,用-f指定你的 rootfs image
初学者建议先用 sample rootfs 把链路跑通。
Q10:我只想更新 bootloader 或只想更新 rootfs
脚本支持:
-b:只更新 bootloader(通常在无布局变化时有意义)-r:只更新 rootfs(同上)
Q11:我想做断电恢复/重试
OTA 在 recovery kernel 中执行。
如果断电重启,系统可能会回到 recovery kernel 并继续。
重试次数由 OTA_MAX_RETRY_COUNT 控制(默认 0)。
Q12:我到底需不需要服务器端
- 跑 demo:不需要(拷贝文件即可)
- 产品化:需要(版本管理、鉴权、安全策略、灰度、监控)
8. 从“demo”到“产品 OTA”,你还缺哪些模块
官方文档把边界说得很清楚:NVIDIA 提供“更新工具链”,但完整的 OTA 解决方案需要你补齐。
你至少要补:
-
OTA server:存放 payload 与 tools
-
OTA client/service(设备端守护进程):
- 周期性检查更新
- 下载 payload/tools
- 校验(签名/哈希/版本白名单)
- 触发
nv_ota_start.sh - 上报结果(成功/失败原因/日志)
-
安全策略:
- payload 签名/加密
- server 鉴权(mTLS/Token)
- 防回滚策略(至少要版本 gate)
-
发布策略:灰度、分批、回滚
如果你希望尽快把“服务器端 + client”做起来,可以参考行业里常见的三类做法:
- 设备管理平台型(例如把 payload 上传到某些设备管理平台,由平台分发)
- OTA 专业平台型(例如集成专业 OTA 平台)
- 自研极简型(Nginx + manifest + systemd service)
9. 真实世界的“全网实例”:别人是怎么把官方 OTA 做成可用方案的
下面这些内容的共同点是:
- payload 仍然是 NVIDIA 的
ota_payload_package.tar.gz - 设备侧触发仍然依赖
nv_ota_start.sh - 差异只在“服务器与客户端”如何封装、如何安全分发与监控
你可以把它们当作“从 demo 走向产品”的参考路线:
- Allxon/Seeed 的 Jetson OTA 指南:强调把 OTA payload 上传到管理平台,然后平台下发到设备触发更新。
- Memfault 的 Jetson OTA 实践:重点在把 Jetson Linux 镜像更新接入到 Memfault 的 OTA 工作流,解决远程批量更新与可观测性。
- Mender 社区对 Jetson 的集成讨论:更偏工程集成(rootfs updater、golden image、与现有 OTA 框架结合)。
这些实例不等同于“官方 demo”,但很适合你理解:NVIDIA 给的是底层更新机制,生态里在其上叠加了 server/client/安全/观测。
10. 一页纸 Checklist:照着做,不容易漏
Host 端
- 准备 BASE_BSP 与 TARGET_BSP(两份 Linux_for_Tegra)
- TARGET_BSP:rootfs 解压 +
apply_binaries.sh - 下载并解压
ota_tools_<rel>_aarch64.tbz2到${TARGET_BSP}/.. - 确认脚本存在:
tools/ota_tools/version_upgrade/l4t_generate_ota_package.sh - 选择
target_board(DevKit 常见:jetson-orin-nano-devkit等) - 运行脚本生成 payload
- 找到 payload 路径:
${TARGET_BSP}/bootloader/<target_board>/ota_payload_package.tar.gz
Device 端
-
df -h /确认空间(建议 7GB+) - 安装
efibootmgr、nvme-cli - 准备
WORKDIR,解压ota_tools_<rel>_aarch64.tbz2 - 准备
/ota/,放入ota_payload_package.tar.gz - 执行
nv_ota_start.sh - reboot,等待更新完成
- 验证:
cat /etc/nv_tegra_release
11. 结语:你跑通 demo 之后,下一步最该做什么
跑通一次官方 demo 的意义是:
- 你确认了 payload 生成链路是 OK 的(Host 工具链 + BSP 制品)
- 你确认了 设备进入 recovery kernel 更新分区这条链路是 OK 的(执行环境与日志路径)
- 你拿到了“失败/成功”的证据入口,后续才谈得上可靠性与产品化
为了让你的学习更系统,我建议你在跑通之后做一次“结构化复盘”:
11.1 用一个“状态机”描述设备侧 OTA(非常推荐)
把你的 OTA client(哪怕现在只是手动操作)抽象为下面 7 个状态:
IDLE
↓ (发现更新)
CHECK_COMPAT (机型/版本/存储形态/白名单)
↓
DOWNLOAD (tools + payload)
↓
VERIFY (hash/signature/decrypt)
↓
STAGE (放到 /ota/,准备 WORKDIR)
↓
TRIGGER (nv_ota_start.sh)
↓ (reboot)
RECOVERY_UPDATE (recovery kernel 中执行)
↓
REPORT (成功/失败/日志上传)
这样做的好处是:
- 你以后接入 server、做灰度、做失败重试,都只是“给状态机加事件与策略”。
- 你排障时也更容易定位:卡在哪个状态?哪一步输入不符合?
11.2 画一张“脚本调用链图”,帮助你快速定位问题
当你看到 nv_ota_start.sh 时,不要把它当成“一个脚本”。它更像是“触发器”。
你可以用下面这张简化调用链来理解:
Host:
l4t_generate_ota_package.sh
└─ 产出 ota_payload_package.tar.gz
Device (正常系统):
nv_ota_start.sh
├─ 解包/准备/校验(按配置)
└─ 触发进入 recovery kernel
Device (recovery kernel):
nv_ota_run_tasks.sh
├─ 任务1:必要的环境/挂载/检查
├─ 任务2:分区写入/切换
├─ 任务3:验证与清理
└─ 失败:写入 /ota_logs/ 并停留/重试
当你遇到问题时,先回答一个问题:
- 问题发生在“正常系统”阶段,还是“recovery kernel”阶段?
如果是后者,直接抓 /ota_logs/,往往比你在正常系统里猜更有效。
11.3 下一步最推荐的学习任务(按优先级)
- 把成功日志也保留下来(便于对照)
- 做一次“可控故障注入”(中途重启/断电),观察是否能继续/如何失败
- 引入最简 server(例如 Nginx 静态文件)+ manifest(json)+ hash 校验
- 再逐步叠加:NVMe → 数据保留 → 自定义任务链 → Secure Boot → Encryption
你会发现:一旦你把“框架”搭好了,后面的高级特性都是“在框架内加约束”。
附录 A:最常用命令速查
# Host:解压 ota_tools 到 TARGET_BSP 的上一级
cd ${TARGET_BSP}/..
sudo tar xjpf ota_tools_<rel>_aarch64.tbz2
# Host:生成 payload
cd ${TARGET_BSP}
sudo -E ./tools/ota_tools/version_upgrade/l4t_generate_ota_package.sh \
jetson-orin-nano-devkit R36-4
# Device:准备并触发
sudo apt-get install -y efibootmgr nvme-cli
mkdir -p ~/ota_work && export WORKDIR=~/ota_work
cd $WORKDIR && sudo tar xjpf ~/ota_tools_<rel>_aarch64.tbz2
sudo mkdir -p /ota && sudo cp ~/ota_payload_package.tar.gz /ota/
cd $WORKDIR/Linux_for_Tegra/tools/ota_tools/version_upgrade
sudo ./nv_ota_start.sh /ota/ota_payload_package.tar.gz
sudo reboot
# 验证
cat /etc/nv_tegra_release
uname -a
📺 B站:博主个人介绍
📘 博主书籍-京东购买链接*:Yocto项目实战教程
📘 加博主微信,进技术交流群: jerrydev
2349



被折叠的 条评论
为什么被折叠?



