1. 项目缘起为什么需要手动刷写BSP如果你手头有一块NVIDIA Jetson开发板无论是入门级的Nano还是性能强悍的AGX Orin从官方渠道拿到手时它通常已经预装了NVIDIA JetPack SDK。这个“开箱即用”的体验固然美好但在实际开发中我们总会遇到一些必须“推倒重来”的场景。比如系统被自己折腾得无法启动需要为特定硬件如定制载板适配全新的板级支持包或者你想将设备恢复到某个已知的、干净的基准状态以确保后续实验的可复现性。这时“刷写BSP”就成了一个绕不开的核心操作。简单来说BSP就是板级支持包它包含了为特定硬件平台定制的Linux内核、设备树、引导加载程序以及一系列基础驱动和固件。而JetPack SDK则是一个更上层的软件栈包含了CUDA、cuDNN、TensorRT等深度学习库以及示例、文档等。我们常说的“刷机”其底层核心动作正是将一份正确的BSP映像文件通过特定的工具和流程完整地写入到Jetson设备的存储中。这个过程听起来简单但新手甚至是有一定经验的开发者都容易在这里踩坑。最常见的误区是混淆了“安装JetPack”和“刷写BSP”。在主机上运行JetPack安装器它会引导你完成驱动安装、进入恢复模式、下载并刷写系统这一系列操作。但当我们谈论“手动刷写BSP”时通常意味着我们跳过了JetPack安装器的图形界面直接使用命令行工具flash.sh并指定一个预先准备好的BSP包通常是一个.tbz2或解压后的文件夹。这种方式更底层、更灵活也更能应对复杂情况比如离线环境、批量部署或深度定制。2. 环境准备主机、设备与BSP包的三角关系手动刷写BSP的成功依赖于三个要素的精确配合一台正确配置的主机、一台处于正确模式的Jetson设备以及一份匹配的BSP文件。任何一环出错都会导致刷写失败。2.1 主机侧Linux环境与必要工具首先你的操作主机强烈建议使用x86_64架构的Ubuntu Linux系统。虽然理论上在虚拟机或WSL2中也能操作但USB连接和恢复模式识别的不稳定性会大幅增加失败概率。物理机安装的Ubuntu 18.04或20.04 LTS版本是经过最广泛验证的。在主机上你需要确保安装了以下基础工具sudo apt update sudo apt install -y qemu-user-static binfmt-support bc build-essential ccache curl g-multilib gcc-multilib git git-lfs gnupg gperf lib32ncurses5-dev lib32z1-dev libc6-dev-i386 libelf-dev libgl1-mesa-dev liblz4-tool libncurses5-dev libsdl1.2-dev libssl-dev libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc zip zlib1g-dev python3 python3-pip这些是编译和操作BSP所需的基础依赖。更重要的是你需要从NVIDIA开发者网站下载对应你Jetson型号的BSP源码包或预编译的BSP释放包。例如对于Jetson AGX Orin你可能会找到一个名为Jetson_Linux_R35.4.1_aarch64.tbz2的文件版本号会变化。将其下载并解压到你的工作目录。2.2 设备侧进入恢复模式的“握手”信号Jetson设备有两种关键启动模式正常模式和强制恢复模式。刷写BSP必须在强制恢复模式下进行。这个模式下的设备其主处理器处于一种特殊状态等待主机通过USB发送刷机指令和映像数据。进入强制恢复模式的标准操作流程是确保设备完全断电拔掉电源适配器。找到设备上的“恢复按钮”。对于Jetson Nano Developer Kit它是一个小孔内的按钮对于AGX Orin工业模组它可能是一个标有“REC”的按钮。先按住恢复按钮不松开。在按住恢复按钮的同时插入电源或Type-C数据/电源线如果支持的话。继续按住恢复按钮约2秒钟然后松开。成功进入恢复模式后设备本身的显示器可能不会有任何反应黑屏但关键在于主机能否识别到它。此时在主机终端执行lsusb命令你应该能看到一个名为“NVIDIA Corp.”的设备其ID通常为0955:7f21或类似。这是主机与设备建立通信的基石。注意这是一个极易出错的环节。如果lsusb没有显示NVIDIA设备请检查USB线是否完好且支持数据传输有些线只能充电是否严格按照“先按按钮再上电”的顺序操作主机USB端口是否正常。可以尝试更换USB端口或数据线并重复上述强制恢复流程。2.3 BSP包确认版本与硬件匹配不是任何一个BSP包都能刷到任何一块Jetson上。你必须确认BSP包的版本与你的硬件型号完全匹配。例如为Jetson AGX Orin 64GB生产的BSP不能用于Jetson AGX Orin 32GB更不用说Jetson Xavier NX了。通常BSP包的文件名或内部README文件会明确说明其适用的硬件。解压BSP包后其目录结构通常包含以下关键部分Linux_for_Tegra/核心目录包含刷机脚本、根文件系统、内核、设备树等。rootfs/根文件系统目录可能是空的需要你根据JetPack版本填充。flash.sh最重要的刷机脚本。在开始刷写前一个良好的习惯是进入Linux_for_Tegra目录快速浏览一下README.txt和flash.sh脚本的头部注释了解其基本用法和任何特定的先决条件。3. 核心流程使用flash.sh脚本进行刷写当主机、设备和BSP包都准备就绪后就可以开始执行核心的刷写命令了。整个过程在主机终端完成。3.1 基本刷写命令解析假设你的BSP包解压后当前终端位于Linux_for_Tegra目录的同级目录。标准的刷写命令如下sudo ./Linux_for_Tegra/flash.sh board rootdev这里有两个关键参数需要你根据实际情况替换board指定你的Jetson设备型号和配置。这个信息定义在BSP包内的配置文件中。常见的例子有jetson-agx-orin-devkit(适用于AGX Orin开发套件)jetson-xavier-nx-devkit-emmc(适用于带eMMC的Xavier NX开发套件)jetson-nano-devkit-emmc(适用于带eMMC的Nano开发套件)jetson-orin-nano-devkit(适用于Orin Nano开发套件) 要找到完整的列表可以查看Linux_for_Tegra/bootloader/boards/目录下的文件或者不带参数运行flash.sh它通常会打印出可用的选项。rootdev指定根文件系统所在的存储设备。对于大多数标准开发套件这通常是内置的eMMC或NVMe存储对应的参数是mmcblk0p1。如果你将系统安装在外接的USB SSD或SD卡上则需要指定对应的设备节点如sda1。因此一个针对Jetson AGX Orin开发套件刷写到内置存储的完整命令示例是cd /path/to/your/bsp sudo ./Linux_for_Tegra/flash.sh jetson-agx-orin-devkit mmcblk0p13.2 刷写过程详解与状态监控执行上述命令后脚本会开始一系列自动化操作。理解这个过程有助于在出现问题时进行排查环境检查脚本首先会检查当前目录结构、必要的工具是否存在并尝试检测连接到主机的恢复模式设备。映像文件准备脚本会根据你指定的board参数组合内核、设备树、引导加载程序等生成一系列将要被刷写的映像文件如boot.img,system.img等。这些临时文件通常生成在Linux_for_Tegra/bootloader/目录下。设备通信与解锁脚本通过USB向处于恢复模式的Jetson设备发送指令建立通信链路。对于某些设备如AGX Orin在首次刷写或刷写不同版本的BSP时可能会涉及设备“擦除”或“解锁”操作这会清除设备上的所有用户数据包括原有的系统、应用和密钥。分块传输与刷写这是最耗时的阶段。脚本会将生成的映像文件分块通过USB传输到Jetson设备并由设备端的引导加载程序将其写入到闪存eMMC或存储设备NVMe的相应分区。终端上会显示进度条和传输日志。刷写完成与重启所有映像传输并验证成功后脚本会向设备发送重启命令。设备将退出恢复模式尝试从新刷写的系统首次启动。在整个过程中请保持设备与主机的USB连接稳定切勿中断电源或拔线。首次启动特别是从eMMC启动可能会比较慢因为系统需要进行一系列初始化配置请耐心等待几分钟。4. 实战避坑常见问题与深度排查指南即使按照指南操作刷机过程也可能遇到各种问题。下面是一些最常见故障的排查思路我将其总结为一张排查决策表你可以根据现象快速定位问题现象可能原因排查步骤与解决方案执行flash.sh后脚本提示“找不到设备”或长时间等待1. 设备未进入恢复模式。2. USB连接或线缆问题。3. 主机USB驱动/权限问题。1. 执行lsusb确认是否有0955:7f21或类似设备。若无严格按2.2节步骤重新操作。2. 更换USB端口和数据线务必使用数据线。3. 尝试在主机上sudo rmmod usbcore sudo modprobe usbcore重置USB核心或重启主机。4. 检查是否有其他程序如虚拟机占用了USB设备。刷写过程中进度条卡住或报错“USB传输错误”1. USB连接不稳定。2. 主机系统资源不足或中断。3. BSP包文件损坏。1. 确保设备供电充足使用原装电源适配器。2. 关闭主机上不必要的程序避免CPU负载过高。3. 重新下载BSP包并验证MD5/SHA256校验和。4. 尝试在主机BIOS中禁用USB省电模式。刷写成功但设备无法启动卡在开机Logo或黑屏1.board参数选择错误。2. 刷写的BSP与硬件不匹配。3. 存储设备损坏。1.仔细核对board参数这是最高频的错误来源。确认你的设备是Developer Kit还是Production Module是16GB还是32GB版本。2. 确认下载的BSP包完全对应你的设备型号。3. 尝试通过串口控制台查看内核启动日志这是最直接的诊断方式。连接串口线在主机使用screen或minicom查看启动信息错误通常会在这里打印出来。首次启动后系统无法完成初始化卡在Ubuntu配置界面1. 根文件系统不完整或损坏。2. 首次启动扩展分区失败。1. 这可能是由于刷写过程中根文件系统传输不完整。建议重新刷写一次。2. 对于某些版本可以尝试在刷写命令后添加-r参数强制重新生成根文件系统sudo ./flash.sh -r board rootdev。需要为定制载板刷写BSP标准BSP不包含定制载板的设备树和配置。1. 你需要获取由载板供应商提供的定制BSP包或者基于NVIDIA的BSP源码进行定制化编译生成包含正确设备树和引脚配置的映像。2. 刷写命令可能需要使用载板供应商提供的特定board配置名。关于串口调试的额外说明对于任何无法启动的严重问题串口控制台都是无可替代的“侦探”。你需要一根USB转TTL串口线连接Jetson上的调试串口通常是J21或J17接口中的UART TX/RX引脚。在主机上使用screen /dev/ttyUSB0 115200端口名可能不同连接。设备上电后所有引导加载程序U-Boot和Linux内核的日志都会输出到这里你可以清晰地看到启动在哪个阶段失败以及具体的错误信息。5. 进阶操作定制化刷写与系统维护掌握了基础刷写后你可以进行更灵活的操作以适应不同的开发需求。5.1 部分刷写与系统更新你并非每次都需要完整刷写整个系统。flash.sh脚本支持仅更新特定组件这在开发内核驱动或更新Bootloader时非常有用。仅更新内核和设备树sudo ./flash.sh -k kernel_name board rootdev。例如-k kernel只刷写内核映像。仅更新Bootloadersudo ./flash.sh -k bootloader_name board rootdev。例如-k bootloader只刷写U-Boot。重新生成并刷写根文件系统sudo ./flash.sh -r board rootdev。这会在保留现有系统设置和用户数据的情况下重建根文件系统映像并刷写但注意根据版本不同此操作有时也可能导致数据丢失重要数据务必备份。5.2 备份与恢复在重大系统修改前备份当前可工作的系统是一个好习惯。虽然NVIDIA没有提供官方的“一键备份”工具但你可以通过以下思路实现进入恢复模式将设备置于恢复模式。使用nvflash工具备份分区flash.sh脚本底层调用的其实是nvflash工具。你可以研究flash.sh的代码提取出对应的命令将--read参数替换--download来将设备上的特定分区如APP,kernel,bootloader读取备份成镜像文件。但这需要你对分区布局有深入了解。基于Rootfs的文件级备份更简单实用的方法是在系统正常运行时使用tar或rsync命令将整个根文件系统/打包备份到外部存储。当需要恢复时先刷写一个干净的BSP然后在首次启动进入系统前通过chroot或在恢复模式下挂载分区将备份的文件还原回去。5.3 与JetPack SDK的协同手动刷写BSP与使用JetPack SDK图形化安装并不冲突它们是不同层面的工具。一个典型的工作流是使用手动刷写建立基准当拿到新设备或需要彻底重置时使用本文介绍的方法刷入一个与目标JetPack版本匹配的、干净的BSP。这确保了硬件层和操作系统层的稳定。使用JetPack SDK安装上层软件在设备系统启动并完成基础配置后你可以通过网络或SD卡在设备上直接运行JetPack SDK的组件安装程序来安装CUDA、cuDNN、TensorRT、VisionWorks等库。这种方式更灵活可以自由选择需要安装的组件。利用SDK Manager进行完整部署对于最省心的方式还是在x86主机上使用SDK Manager。它会自动处理主机端驱动安装、设备进入恢复模式、下载匹配的BSP并刷写、以及后续所有深度学习库的安装实现一站式部署。手动刷写的价值在于它让你摆脱了对图形界面和网络下载的依赖让你能精确控制刷入系统的每一个字节在离线环境、自动化脚本和深度定制场景下这是唯一可靠的方法。每一次成功的刷写都是你对Jetson设备底层理解加深的一步。