1. 项目缘起:一次看似简单的固件升级
最近在折腾一块基于瑞芯微RV1126芯片的开发板,核心任务是给它升级固件。这听起来是个常规操作,对吧?无非就是找个烧录工具,选好镜像,点一下“升级”按钮。但实际情况是,从准备镜像、选择升级模式,到处理升级过程中的各种“幺蛾子”,每一步都可能藏着坑。RV1126作为一款面向视觉AI应用的SoC,其固件升级流程相比一些简单的MCU要复杂得多,它涉及到Bootloader、分区表、内核、文件系统等多个层面的协同工作。我这次的目标不仅仅是把新固件刷进去,更是要彻底搞清楚整个升级链路的来龙去脉,以及当升级失败时,如何通过有限的调试手段(比如串口)快速定位问题。如果你也在玩RV1126、RK3568或者其他Rockchip平台的设备,并且对“烧写镜像”、“OTA升级”、“串口调试”这些关键词感到既熟悉又头疼,那么我踩过的这些坑和总结的经验,或许能帮你省下不少折腾的时间。
2. 升级前的“战备”工作:工具与环境梳理
在动手升级之前,把工具和环境理顺了,能避免至少一半的莫名其妙的问题。很多人一上来就急着连板子、开软件,结果卡在第一步。
2.1 核心工具三件套:烧写、调试与镜像
对于Rockchip平台,尤其是RV1126,下面这三个工具是你的必备武器:
RKDevTool / Upgrade Tool:这是瑞芯微官方的烧录工具。不同芯片型号、不同版本的工具可能存在兼容性问题。一个常见的坑是,你从某个论坛下载的“通用版”工具,可能根本不识别你的RV1126板子。我的经验是,优先从板卡供应商或方案商那里获取配套的工具。如果找不到,可以去Rockchip的官方Wiki或开发者社区寻找对应芯片型号的专用版本。工具界面通常有“Loader”和“Maskrom”两种烧录模式,这个我们后面会详细讲。
串口调试助手:这是你的“眼睛”和“嘴巴”。在升级过程中,尤其是当系统无法正常启动时,串口是获取Bootloader和内核日志的唯一通道。
sscom、xcom、putty、minicom都可以。关键参数就三个:波特率(RV1126通常为1500000)、数据位8、停止位1、无校验。这里有个细节:一定要确保串口线的驱动正确安装,并且在设备管理器中确认了正确的COM口号。我遇到过无数次因为COM口选错,导致看着一片空白的终端发呆的情况。固件镜像文件:通常是一个
.img文件,或者由多个分区镜像打包而成的update.img。你需要确认这个镜像是否与你的硬件版本(如DDR型号、PMIC配置)完全匹配。用不匹配的镜像轻则功能异常,重则直接“变砖”。在拿到镜像后,可以尝试用7zip或binwalk工具简单查看一下内部结构,确认它包含boot.img、rootfs.img等关键分区。
2.2 系统环境与驱动确认
如果你的工作机是Windows,那么DriverAssitant(驱动助手)这个工具必须安装。它包含了Rockchip芯片进入升级模式(Maskrom或Loader)时所需的USB驱动。安装后,最好在设备管理器中手动检查一下,当板子进入升级模式并连接USB后,是否会正确识别为“Rockchip USB Device”或类似的设备。
如果是Linux环境进行升级,则需要配置udev规则,让普通用户也能访问USB设备,并且使用rkdeveloptool等命令行工具进行操作。这部分的坑在于权限和工具链的版本匹配。
注意:在连接板子之前,先打开串口调试助手并设置好参数,然后再给板子上电。这样你才能捕获到最完整的启动日志,从Bootloader的第一行输出开始看起。这是判断板子状态的第一手资料。
3. 深入RV1126的升级模式:Loader与Maskrom的区别
这是理解Rockchip平台升级的关键。很多升级失败,根源就在于模式没选对。
3.1 Loader模式:常态化的升级入口
当RV1126板子里的Bootloader(通常是U-Boot)正常运行时,并且这个U-Boot支持rockusb或rkusb命令时,就可以进入Loader模式。
- 如何进入:通常有两种方式:
- 在串口终端中,在U-Boot的倒计时阶段按下任意键打断自动启动,然后输入命令
rkusb或rockusb。 - 板子上可能有专门的“升级键”(Recovery键),在板上电瞬间按住此键,U-Boot会检测到并自动进入Loader模式。
- 在串口终端中,在U-Boot的倒计时阶段按下任意键打断自动启动,然后输入命令
- 表现:进入Loader模式后,串口可能会输出
Enter rockusb mode之类的提示,同时Windows电脑会识别到一个新的USB设备。此时在RKDevTool中,设备列表会显示为一个“发现一个LOADER设备”。 - 特点:Loader模式依赖于板载Bootloader的正常工作。如果Bootloader本身损坏了,这个模式就进不去了。
3.2 Maskrom模式:救砖的终极手段
Maskrom是芯片内部固化的一段只读启动代码。当系统检测不到任何有效的可启动设备(如eMMC、SPI Flash为空或损坏)时,或者通过特殊引脚强制触发时,芯片会自动 fallback 到 Maskrom 模式。
- 如何进入:这是重点,也是硬件操作。
- 短路Flash:找到板载eMMC或SPI Flash芯片的数据引脚(通常是
D0或CLK),在上电瞬间将其与地(GND)短接。这模拟了Flash无法识别的状态,迫使芯片进入Maskrom。这是最通用的方法,但需要一定的硬件动手能力,并要查询你板子的原理图。 - 专用测试点:有些开发板会设计一个标记为“Maskrom”或“M”的测试点,将其在上电瞬间与地短接即可。
- 按键组合:极少数板子可能有通过按住多个按键上电的方式触发。
- 短路Flash:找到板载eMMC或SPI Flash芯片的数据引脚(通常是
- 表现:进入Maskrom模式后,芯片会等待主机通过USB发送下载指令。在RKDevTool中,设备会显示为“发现一个MASKROM设备”。
- 特点:这是最底层的模式,不依赖任何外部存储器的代码。只要芯片本身没坏,就能通过Maskrom模式重新烧写Bootloader,从而实现“救砖”。
3.3 模式选择与实战策略
理解了这两种模式,你的升级策略就清晰了:
- 常规升级:板子能正常启动到U-Boot或系统 -> 优先尝试进入Loader模式进行升级。这种方式最安全、最方便。
- 救砖/首次烧录:板子无法启动、Flash为空、或升级中途失败导致Bootloader损坏 -> 必须使用Maskrom模式。
我遇到的一个典型场景是:在Loader模式下升级,中途因为USB线松动或电源波动导致升级中断,结果Bootloader被写坏了一半。此时板子既无法正常启动,也无法再次进入Loader模式。唯一的办法就是拆开机壳,找到Flash引脚,用镊子短接进入Maskrom模式,重新烧写完整的固件。
4. 固件镜像的构成与烧写流程拆解
知道怎么连接板子了,我们再来看看要烧写的“固件”到底是什么。一个完整的RV1126升级镜像,通常不是单一文件,而是一个遵循特定格式的包。
4.1 标准update.img的解析
使用RKDevTool烧写时,我们常选择一个update.img文件。这个文件其实是一个容器,里面打包了多个分区镜像和一份分区表信息。你可以使用Rockchip提供的afptool和img_unpack工具对其进行解包:
# 假设在Linux环境下 ./afptool -unpack update.img update/ ./img_unpack update.img rockimg/解包后,你可能会看到如下关键组件:
parameter.txt:分区表文件。这是升级的“地图”,定义了eMMC上各个分区(如boot,rootfs,userdata)的起始位置、大小和名称。升级前务必确认此分区表与板子原有分区布局兼容,否则可能导致数据错乱。boot.img:包含内核(kernel.img)和设备树(resource.img或dtb)等。负责启动Linux系统。rootfs.img:根文件系统,包含了操作系统的基础命令、库和你的应用程序。misc.img:用于OTA升级时传递状态信息的分区。userdata.img:用户数据分区。
4.2 RKDevTool烧写步骤详解
在RKDevTool中,烧写流程是这样的:
- 工具读取
update.img中的parameter.txt。 - 根据分区表,将
boot.img、rootfs.img等逐个通过USB传输到板端的Bootloader(Loader模式)或Maskrom。 - Bootloader/Maskrom程序将这些镜像写入eMMC对应的物理地址。
这里有一个至关重要的选项:“擦除Flash”和“擦除IDB”。
- 擦除Flash:会清空整个存储设备(eMMC)的所有数据。相当于格式化整个硬盘。
- 擦除IDB:IDB是存储在Flash前几个块的信息块,包含了Bootloader和分区表信息。擦除IDB会破坏Bootloader和分区表。
实操心得:
- 首次烧录或彻底重刷:可以勾选“擦除Flash”,确保一个干净的状态。
- 常规升级:千万不要勾选“擦除Flash”!特别是你的
userdata分区里有重要数据时。标准的升级流程只会覆盖boot、rootfs等系统分区,保留userdata分区。RKDevTool在加载update.img后,通常默认只勾选需要更新的分区(如boot,rootfs),这是安全的。- “擦除IDB”要慎用:只有在分区表损坏或需要彻底更换Bootloader类型(如从旧版U-Boot换成新版)时才使用。误操作会导致板子无法启动,必须进Maskrom。
4.3 命令行烧写:更底层的控制
在Linux主机上,你可以使用rkdeveloptool进行更灵活的烧写。这对于自动化脚本或深入了解流程非常有帮助。
# 1. 查看连接的设备 rkdeveloptool ld # 输出示例:DevNo=1 Vid=0x2207,Pid=0x350b,LocationID=106 Maskrom # 2. 下载并运行Loader(用于Maskrom模式初始化) rkdeveloptool db rkbin/RK1126_Loader.bin # 3. 烧写整个update.img rkdeveloptool wl 0 update.img # 4. 或者,分别烧写各个分区(更灵活) rkdeveloptool ppt # 查看分区信息 rkdeveloptool wl boot boot.img rkdeveloptool wl rootfs rootfs.img命令行工具让你对每个步骤都有清晰的控制,当图形化工具出错时,命令行输出的错误信息往往更直接。
5. 串口调试:当升级出错时,你的诊断利器
升级过程很少一帆风顺。当RKDevTool卡住、报错,或者烧写成功后板子依然无法启动时,串口调试终端就是你的救命稻草。你需要学会解读这些日志。
5.1 Bootloader启动日志分析
上电后,串口最先输出的是Bootloader(U-Boot)的信息。健康的日志链是这样的:
U-Boot 2017.09 (Mar 01 2023 - 10:00:00 +0800) Model: Rockchip RV1126 Evaluation Board DRAM: 1 GiB MMC: dwmmc@ffc50000: 1, dwmmc@ffc60000: 0 In: serial Out: serial Err: serial ... Hit any key to stop autoboot: 3如果在这里就卡住了,比如DRAM初始化失败,那可能是DDR配置不对(镜像与板子硬件不匹配),或者板子硬件有问题。
5.2 内核启动日志与常见故障
Bootloader之后,会将控制权交给内核。内核启动日志非常详细,能暴露大部分问题:
[ 0.000000] Booting Linux on physical CPU 0x0 [ 0.000000] Linux version 4.19.111 (build@server) ... [ 0.000000] Machine model: Rockchip RV1126 Evaluation Board ... [ 1.234567] dwmmc_ffc50000: voltage-ranges unspecified [ 1.234568] dwmmc_ffc50000: 1, dwmmc_ffc60000: 0 [ 1.567890] mmc0: new high speed SDHC card at address aaaa [ 1.567891] mmcblk0: mmc0:aaaa SL32G 29.7 GiB ... [ 2.345678] VFS: Mounted root (ext4 filesystem) on device 179:2. [ 2.345679] devtmpfs: mounted [ 2.456789] Freeing unused kernel memory: 1024K [ 2.456790] Run /sbin/init as init process常见错误及排查方向:
卡在
Starting kernel ...之后没有任何输出:- 最可能的原因:设备树(
dtb)错误。Bootloader加载了错误的内核或设备树文件,导致内核无法识别硬件而崩溃。解决方法:检查boot.img中的设备树是否与你的板型完全匹配。回退到已知正常的旧版本镜像进行对比。
- 最可能的原因:设备树(
内核恐慌(Kernel Panic):
[ 3.000000] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)- 原因:内核找不到根文件系统。可能是
rootfs镜像损坏、分区表错误导致根文件系统分区位置不对、或者内核缺少对应的文件系统驱动(如ext4)。 - 排查:首先确认
parameter.txt中rootfs分区的名称和编号是否正确。在U-Boot中使用mmc part或part list mmc 0命令查看实际分区表。确认内核配置包含了对应的文件系统支持。
- 原因:内核找不到根文件系统。可能是
MMC/SD卡初始化失败:
[ 1.500000] dwmmc_ffc50000: error -110 whilst initialising MMC card- 原因:存储设备初始化失败。可能是eMMC芯片虚焊、损坏,或者内核驱动中的时序配置(如
dwmmc节点的clock-frequency)与硬件不匹配。 - 排查:检查硬件连接。对比正常板子的内核设备树中MMC控制器的配置。
- 原因:存储设备初始化失败。可能是eMMC芯片虚焊、损坏,或者内核驱动中的时序配置(如
5.3 文件系统挂载失败与Init进程问题
即使内核启动成功,也可能在挂载根文件系统或启动第一个用户进程init时失败。
[ 2.500000] List of all partitions: [ 2.500001] ... (分区列表正常) ... [ 2.500002] VFS: Cannot open root device "mmcblk0p5" or unknown-block(0,0): error -6 [ 2.500003] Please append a correct "root=" boot option; here are the available partitions: ...这明确指出了根设备mmcblk0p5无法打开。你需要检查:
- U-Boot的
bootargs环境变量中root=参数指定的设备是否正确(例如root=/dev/mmcblk0p5)。 - 对应的分区(这里是第5分区)是否存在且包含有效的文件系统镜像。
如果挂载成功,但最后卡在Run /sbin/init as init process,然后没有下文,通常是根文件系统里的/sbin/init链接(通常指向systemd或busybox)损坏,或者文件系统本身不完整。这通常意味着rootfs.img在制作或烧写过程中出了问题。
6. OTA升级:远程部署的关键机制
对于量产设备,我们不可能每次都拆机短接用USB升级。OTA(Over-The-Air)升级是必须的。RV1126的OTA升级核心是recovery系统。
6.1 Recovery系统与A/B分区
一种常见的OTA方案是使用recovery分区。当系统需要升级时,会重启进入recovery分区(一个精简的Linux系统),由recovery来完成对主系统分区(boot,system,vendor等)的更新。 Rockchip也支持A/B分区(无缝更新)方案,即有两套完整的系统分区(A槽和B槽),当前运行A槽,后台更新B槽,下次启动时从B槽启动。这需要Bootloader(如U-Boot)和系统(Android Things或某些Linux发行版)的支持。
6.2 制作OTA升级包
OTA升级包(ota_update.zip或update.zip)不同于完整的update.img。它通常是一个差分包或全量包,只包含需要更新的分区镜像,并附带一个升级脚本updater-script(用于Android兼容的recovery)或自定义的更新逻辑。 制作OTA包通常需要使用SDK中的编译脚本,例如build.sh或mkupdate.sh,它会根据版本差异生成对应的包。
6.3 OTA升级流程与调试
- 下载:设备从服务器下载OTA升级包到缓存分区(如
cache)或数据分区。 - 验证:验证包的签名和完整性,防止被篡改。
- 进入Recovery:系统重启,Bootloader根据升级标志(常存储在
misc分区)决定启动到recovery系统。 - 安装更新:
recovery系统解压升级包,根据脚本擦写对应的系统分区。 - 重启:更新完成后,清除升级标志,重启进入主系统。
调试OTA的难点在于,更新过程发生在recovery里,而recovery的串口日志可能和主系统不同,或者根本没有输出。你需要:
- 确保
recovery镜像本身包含了串口驱动和输出功能。 - 在
recovery的初始化脚本(如init.rc)中,确保console被正确设置到串口。 - 仔细检查升级脚本的逻辑,确保分区挂载、文件拷贝、权限设置的每一步都正确。
我遇到过一个典型的OTA失败案例:升级包制作时,文件路径使用了绝对路径/system/bin/app,但recovery环境下/system可能并未挂载,导致文件拷贝失败。正确的做法是在脚本中先挂载system分区到某个临时目录(如/tmp/system),再进行操作。
7. 进阶排查:当基础手段都失效时
如果串口没有任何输出,或者输出乱码,问题就更底层了。
7.1 串口无输出排查
- 硬件连接:TX/RX线是否接反?串口板(如USB转TTL)的电压是否是3.3V(RV1126通常是3.3V电平)?地线是否接好?
- 波特率:尝试最常见的
1500000,也试试115200。有些Bootloader早期阶段可能用低速波特率。 - Bootloader损坏:如果完全无输出,且确认串口硬件和设置无误,那很可能是Bootloader代码区域(IDB)完全损坏。此时必须尝试Maskrom模式。
7.2 使用示波器或逻辑分析仪
对于更棘手的启动问题,比如DDR无法初始化,软件日志无能为力。这时需要硬件工具。
- 测量时钟和电源:用示波器检查核心电压(如
VDD_LOGIC)、DDR电压是否稳定且在正确范围内。检查主晶振是否起振。 - 抓取eMMC引脚波形:在启动瞬间,用逻辑分析仪抓取eMMC的
CLK和CMD线波形,看Bootloader是否在尝试读取Flash。如果没有读写活动,说明芯片可能没跑起来,或者BootROM(Maskrom)在更早阶段就失败了。
7.3 利用TrustZone调试输出(如果有)
RV1126的Arm Cortex-A7核心通常运行在非安全世界(Linux),而安全世界(TrustZone)可能运行着OP-TEE等安全OS。有些调试信息可能会输出到安全世界的UART上,而这个UART可能和Linux使用的不是同一个物理串口。如果你的板子有多个UART接口,可以尝试连接其他UART引脚,看看是否有不同的输出。这需要查阅芯片的TRM(技术参考手册)和板子的原理图。
整个RV1126的升级调试,是一个从软件到硬件、从上层应用到底层硬件的全链路认知过程。最深刻的体会就是:日志是你的第一线索,理解流程是你分析线索的地图,而硬件操作(如Maskrom)是你最后的保障。每次升级前,做好备份,确认镜像匹配,理解你每一步操作的意义,这样才能在遇到问题时从容不迫,一步步缩小范围,最终找到那个捣鬼的“小妖精”。