系列第四篇。前三篇我们只往内存里写代码;这一篇开始碰 Flash。
本文围绕 ATK-DLRK3506B + Ubuntu,梳理 Rockchip 烧写模式、进入 MaskROM/Loader 的方法、upgrade_tool常用命令,以及实际踩过的坑。
摘要
本文主要讲清楚四件事:
Rockchip 平台下 MaskROM / Loader / Recovery / Normal Boot 的区别;
ATK-DLRK3506B 上如何正确进入 MaskROM;
Ubuntu 下如何用
upgrade_tool/rkdeveloptool识别设备、下载 Loader;真正写 Flash 的
UF/WL命令及其风险。
一句话结论:动手改 Loader / 分区表之前,先确认自己能进 MaskROM。那是唯一的“变砖救援”入口。
⚠️ 本文实测边界
请先看这一段:
文中
lsusb/upgrade_tool LD的输出;按键进入 MaskROM / Loader 的方法;
MaskROM 下
RCI/RFI失败的现象;
但DB / UF / WL 这些真正涉及存储读写的命令,本文作者尚未实测。文中会逐条标注。命令出自官方工具帮助与手册,实操前请自行确认风险。
目录
1. 烧写模式介绍
2. ATK-DLRK3506B 按键对应关系
3. 进入 MaskROM
4. MaskROM 下一步:DB 下载 Loader
5. 真正写 Flash:UF / WL
6. rkflash.sh 与 upgrade_tool 怎么选
附录 A:命令速查
附录 B:状态速查
附录 C:本文实测边界
1. 烧写模式介绍
Rockchip 平台硬件设备常见运行模式如下。
只有当设备处于MaskROM或Loader模式时,并且通过 USB 线将开发板 OTG 口连接到电脑,才能烧写镜像或更新板上镜像。
| 模式 | 是否支持烧录 | 描述 |
|---|---|---|
| MaskROM | 支持 | Flash 未烧录镜像时,芯片会引导进入 MaskROM,可进行初次镜像烧写;调试过程中若无法正常进入 Loader,也可进 MaskROM 烧写 |
| Loader | 支持 | 可进行镜像烧写、更新升级;可通过烧写工具单独烧写某一个分区镜像,方便调试 |
| Recovery | 不支持 | 通过引导 recovery 镜像进入,主要用于升级、恢复出厂设置 |
| Normal Boot | 不支持 | 系统正常启动,引导 rootfs,加载根文件系统,大多数开发在此模式下进行 |
1.1 进入 MaskROM 的通用方法
先连接电源适配器和 OTG。
开发板未烧录过镜像:上电后自动进入 MaskROM;
开发板烧录过镜像:按住 UPDATE 键(板子不同,没有此按键则按 MASKROM 键),然后上电或复位;
开发板烧录过镜像:按住 V- 键(音量-),然后上电或复位;
在 U-Boot 命令行下执行
rbrom。
1.2 进入 Loader 的通用方法
先连接电源适配器和 OTG。
按住 V+ 键(音量+)(没有则按 RECOVER 键),然后上电或复位;
在 U-Boot 命令行下执行
download;在 Linux 系统下,通过串口或 ADB 执行
reboot loader。
出处:正点原子《固件烧写参考手册 V1.0》§2.1 · PDF 第 11 页。
2. ATK-DLRK3506B 按键对应关系
手册是通用文档,里面提到的是手机板的 V+ / V- / UPDATE 键。
但ATK-DLRK3506B 上根本没有这些键。实际对应关系如下,已用单键隔离实验实测确认:
| 目标 | 按键 | 丝印 | 拉低的 ADC | 由谁采样 | 主机上看到 |
|---|---|---|---|---|---|
| MaskROM | KEY2 | MASKROM | SARADC_IN0_BOOT | BootROM | 2207:350f + bcdUSB 2.00 |
| Loader | KEY3 | RECOVERY | SARADC_IN1_RECOVER | Loader 阶段 | 2207:350f + bcdUSB 2.01 |
| 复位 | KEY1 | RESET | — | NPOR_L | — |
对应关系:
手册的 “UPDATE / MASKROM 按键” → 本板KEY2
手册的 “RECOVER 按键” → 本板KEY3
本板没有 V+ / V- 音量键
两者谁更可靠?KEY2。
因为它由 BootROM 采样,不依赖板上任何固件;而 KEY3 由 Loader 阶段采样,依赖 Loader 区完好。
所以:改 Loader / 分区表之前,先确认自己会进 MaskROM。
3. 进入 MaskROM
3.1 第一步:确认线插对了口(本文最值钱的一段)
ATK-DLRK3506B 上有两个长得一模一样的 Type-C 口,用途完全不同:
| 口 | 位置 | 用途 | 主机上看到 | 能烧写吗 |
|---|---|---|---|---|
| 标 USART 丝印的 Type-C | 底板 | 调试串口(CH343) | 1a86:55d3 | ❌ 不能 |
| 核心板上的 Type-C | 核心板 | USB 从机 / OTG | 2207:xxxx | ✅ 就靠它 |
正点原子《ATK-DLRK3506B 快速体验 V1.2》§3.3.2 原文:
在 ATK-CLRK3506B 核心板上有一个 USB TypeC 接口,这个接口可以使用 adb 功能,就是作为从机。……另一个标有 USART 丝印的 USB TypeC 接口不做 ADB 功能。
🚨这是我实际踩过的坑:
一开始把线插在 USART 口上,lsusb里只有1a86:55d3,一个2207都没有。按 KEY2 按了很多次都毫无反应——因为烧写根本不走那根线。
💡一分钟自检法:
把线插到核心板 Type-C 后,让板子正常启动 Linux(不用按任何键)。
如果lsusb出现2207:0006(ADB 设备),说明口找对了、线也是数据线。
口不对的话,按键按多少次都不会有反应。
3.2 第二步:按键进 MaskROM
✅不需要拔掉调试串口。
实测两根线可以同时插着——主机上1a86:55d3(调试串口)与2207:350f(rockusb)并存,互不影响。正常开发时“调试串口 + OTG”两根线都插着即可。
⚠️但要拔的是 OTG 那根,不是标 USART 丝印的那根。
本板实测可以用「拔掉 OTG 线(标 USART 丝印的那根)→ 再插回去」当作断电重上电来用。
推荐手法:先按住键,再上电。
拔掉 OTG 那根 USB 线(板子断电);
按住核心板 KEY2(丝印 MASKROM)不放;
保持按住,把 OTG 线插回去(板子上电);
继续按住 3–5 秒,再松手。
或者只用板上的按键:
按住 KEY2 不放;
保持按住,按一下 KEY1(RESET);
继续按住 3–5 秒,再松手。
🎯优先用第一种:先按住键、再上电。
不要用“一只手按住键、另一只手去按 RESET”——采样那一瞬间很容易已经松手。
实测中 KEY3 用 RESET 方式失败过 1 次,改用断电冷启动立刻成功。
3.3 第三步:验证是否进入 MaskROM
方法 1:只看有没有(最简单,不需要 root)
bash
lsusb -d 2207:
实测输出:
text
Bus 003 Device 116: ID 2207:350f Fuzhou Rockchip Electronics Company
看到这行,就说明 BootROM 已经在 USB 下载循环里了。
方法 2:区分是 MaskROM 还是 Loader(不需要 root)
第一步:先列出所有 USB 设备端口
bash
ls /sys/bus/usb/devices/
实测输出类似:
text
1-0:1.0 3-1 3-10:1.1 3-2:1.0 3-4 3-4.1:1.0 3-4.2:1.0 3-4.4 3-6:1.0 4-0:1.0 usb3 2-0:1.0 3-10 3-1:1.0 3-2:1.1 3-4.1 3-4.1:1.1 3-4.2:1.1 3-4.4:1.0 3-6:1.1 usb1 usb4 3-0:1.0 3-10:1.0 3-2 3-2:1.2 3-4:1.0 3-4.2 3-4.3 3-6 3-6:1.2 usb2
这里先建立一个概念:
带
:的,比如3-4.4:1.0,是 USB 接口;不带
:的,比如3-4.4,才是 USB 设备;usb1/usb2/usb3/usb4是根 Hub,不是我们要找的设备;我们要找的 Rockchip 设备,通常是这种不带
:的目录。
第二步:从端口里找出 Rockchip(VID 2207)
不用一个个点开,直接终端执行:
bash
grep -H 2207 /sys/bus/usb/devices/*/idVendor
实测输出类似:
text
/sys/bus/usb/devices/3-4.4/idVendor:2207
这里/sys/bus/usb/devices/3-4.4/idVendor说明端口就是:
text
3-4.4
如果你想看得更完整,也可以执行:
bash
for d in /sys/bus/usb/devices/*; do [ -f "$d/idVendor" ] || continue if [ "$(cat "$d/idVendor")" = "2207" ]; then echo "端口: $d" echo -n "VID:PID = " cat "$d/idVendor"; echo -n ":"; cat "$d/idProduct"; echo echo -n "bcdUSB = " cat "$d/version" echo fi done
输出会类似:
text
端口: /sys/bus/usb/devices/3-4.4 VID:PID = 2207:350f bcdUSB = 2.00
第三步:看 version,判断模式
知道端口后,直接看这个端口的version:
bash
cat /sys/bus/usb/devices/3-4.4/version
输出可能是:
text
2.00
或者:
text
2.01
判断规则:
bcdUSB末位 | 模式 |
|---|---|
| 2.00 / 1.10 / 2.10 偶 | MaskROM |
| 2.01 / 1.11 奇 | Loader |
也就是说:
text
2.00 -> MaskROM 2.01 -> Loader
原理:upgrade_tool/rkdeveloptool自己就是靠这个最低位判型的。
源码RKScan.cpp:400-405:
cpp
usTemp = (*iter).usbcdUsb & 0x1; if (usTemp == 0) (*iter).emUsbType = RKUSB_MASKROM; else (*iter).emUsbType = RKUSB_LOADER;
所以 MaskROM 和 Loader 是同一个 PID2207:350f,唯一区别就在这一位。
可选:一条命令自动判断
如果不想分三步,也可以直接把下面这段扔进终端:
bash
for d in /sys/bus/usb/devices/*; do [ -f "$d/idVendor" ] || continue if [ "$(cat "$d/idVendor")" = "2207" ]; then v=$(cat "$d/version" 2>/dev/null) [ -n "$v" ] || continue last=${v##*.} if [ $((last % 2)) -eq 0 ]; then mode="MaskROM" else mode="Loader" fi echo -n "$d VID:PID=" cat "$d/idVendor"; echo -n ":"; cat "$d/idProduct" echo " bcdUSB=$v Mode=$mode" fi done输出示例:
text
/sys/bus/usb/devices/3-4.4 VID:PID=2207:350f bcdUSB=2.00 Mode=MaskROM
看到Mode=MaskROM或Mode=Loader即可。
在这里我写了个shell来方便快速判断,并附带视频如下:
源码可见:
4. MaskROM 下一步:DB 下载 Loader
MaskROM 状态下能做的事非常有限。
一个很有说服力的反证(实测):
bash
$ sudo ./upgrade_tool RCI Read Chip Info quit,Creating comm object failed! $ sudo ./upgrade_tool RFI Read flash Info quit,Creating comm object failed!
原因是RCI(读芯片信息)/RFI(读 Flash 信息)/PL(分区表)这些命令都要Loader 在线才支持,BootROM 不管这些。
4.1 下载 Loader
MaskROM 的第一步永远是:
bash
sudo ./upgrade_tool DB MiniLoaderAll.bin
DB = DownloadBoot:把 Rockchip 的 Loader(MiniLoaderAll.bin)下载进 SRAM/DDR 并运行它。它会初始化 DDR,并提供完整的 rockusb 协议。
物理机 Ubuntu 下,
DB需要写 USB 设备,直接加sudo运行即可。如果不想每次都 sudo,可以配置 udev 规则,但图省事的话直接 sudo 最方便。
✅DB不写 Flash,是安全的——按一下 RESET 就完全恢复。
⚠️ 但本文作者尚未实测这一步,命令出自官方工具帮助与手册。
下载成功后设备会变成 Loader 模式:
LD的输出里Mode=变成Loader;bcdUSB也从2.00变成2.01。
MiniLoaderAll.bin 从哪来?
可以从这些位置找:
开发板资料 A 盘:
05、开发工具/02、RKTools/windows/RKDevTool/rockdev/rk3506-package-file/或从官方
update.img里拆出来:rkImageMaker -unpack
5. 真正写 Flash:UF / WL
到这一步才是“烧写”两个字的本意。
5.1 整包升级:UF
bash
sudo ./upgrade_tool UF rk3506b_update_ubi_squashfs.img
⚠️风险与前提:
这会覆盖板上 SPI NAND 里的整个系统,写了就回不去,除非再烧回来;
本板没有 eMMC,存储是 SPI NAND + TF 卡,所以要用
rk3506b_update_ubi_*.img(NAND 用),不是rk3506b_update_sd.img(那个是给 TF 卡的);动手前必须先确认自己能进 MaskROM(§3)——那是唯一的救援入口;
⚠️ 本文作者尚未实机执行过这一步,命令出自手册与工具帮助。
5.2 单独烧某个分区:WL
开发调试更常用的是WL(WriteLBA),按扇区号写。
🚨WL 的参数是存储扇区号(LBA),不是内存地址!
写错 LBA 会破坏分区表,务必先查 SDK 的parameter.txt。
6. rkflash.sh 与 upgrade_tool 怎么选
正点原子《固件烧写参考手册 V1.0》§2.3 用的是 SDK 顶层脚本:
bash
sudo ./rkflash.sh uboot # 只烧 uboot sudo ./rkflash.sh all # 全烧 sudo ./rkflash.sh update # 烧 update.img
它确实方便,但前提是你已经下载并解压了 SDK 源码。脚本在 SDK 顶层,工具在:
text
<SDK>/tools/linux/Linux_Upgrade_Tool/
如果手上还没有 SDK,官方upgrade_tool是等价的独立工具,不需要 SDK。开发板资料 A 盘里就有:
text
A盘/05、开发工具/02、RKTools/linux/Linux_Upgrade_Tool/
💡 顺带一提:手册 §2.3 自己也写着“Ubuntu 下烧写不是必须的”,并建议先在 Windows 下完成一次烧写,确认线和流程都正常,再来折腾 Ubuntu 下的连接时机。
附录 A:命令速查
| 目的 | upgrade_tool | rkdeveloptool |
|---|---|---|
| 列设备 | LD | ld |
| 下载并运行 Loader(初始化 DDR) | DB <Loader> | db <Loader> |
| 读芯片信息 | RCI(需 Loader 在线) | — |
| 读 Flash 信息 | RFI(需 Loader 在线) | — |
| 分区表 | PL(需 Loader 在线) | — |
| 整包升级 | ⚠️UF <update.img> | uf <update.img> |
| 写 LBA | ⚠️WL <BeginSec> <File> | wl <BeginSec> <File> |
| 复位设备 | RD | rd |
⚠️ 官方upgrade_tool里没有“写内存并执行”的命令;rkdeveloptool上游版也没有。本项目用的是打过补丁、加了wm/rm/rexec的版本。
附录 B:状态速查
| 主机上看到 | 含义 | 能做什么 |
|---|---|---|
没有2207 | 不在烧写模式 | 什么都烧不了 |
2207:350f+bcdUSB偶(2.00) | MaskROM | 只能先DB下 Loader |
2207:350f+bcdUSB奇(2.01) | Loader | 可直接写存储/分区 |
2207:0006 | ⚠️ 板子在跑 Linux(ADB 设备) | 禁止DB/WM/rexec |
附录 C:本文实测边界
| 内容 | 状态 |
|---|---|
| KEY2 → MaskROM、KEY3 → Loader 的按键对应 | ✅ 实机实测(单键隔离实验) |
2207:350f + bcdUSB奇偶判型 | ✅ 实机实测 + 与官方工具交叉验证一致 |
lsusb/upgrade_tool LD/rkdeveloptool ld的输出 | ✅ 实机实测 |
MaskROM 下RCI/RFI失败 | ✅ 实机实测 |
LD不需要 sudo、DB/RCI/RFI必须 sudo(否则Creating Comm Object failed!) | ✅ 实机实测(含/dev/bus/usb权限核对) |
| 两个 Type-C 口的用途区分 | ✅ 手册原文 + 实机端口观察 |
| 调试串口与 OTG 可同时插着 | ✅ 实机实测(两设备并存) |
DB下载 Loader 成功 | ⚠️ 未实测(本机 sudo 需密码,待补) |
Loader 下RCI/RFI/PL能否成功 | ⚠️ 未实测(依赖上一条) |
UF/WL真正写 Flash | ⚠️ 未实测 |
本文实测部分对应的原始证据:
text
../data/evidence/boot_mode_probe_20260926.md ../data/evidence/mode_key_mapping_20260926.log
结语
Ubuntu 下烧写 RK3506,最容易卡住的不是命令本身,而是:
线插错口:把 OTG 插到了 USART 口;
按键时序不对:没有先按住 KEY2 再上电;
权限不够:
LD能跑,DB却报Creating Comm Object failed!;MaskROM 下乱试命令:
RCI/RFI/PL本来就需要 Loader 在线;还没确认能进 MaskROM,就急着改 Loader / 分区表。
再强调一次:先确认自己能稳定进入 MaskROM,再动 Flash。