瑞芯微平台 · SPI NAND / eMMC 量产排查
编制日期 2026-09-21 | 版本号 Rev 1.0
XTX 芯天下 · FAE 现场技术文档 | 瑞芯微(Rockchip)系列 SoC 外挂 SPI NAND 与 eMMC 的烧录与启动失败定位 (RK3308 / RK3328 / PX30 / RK3566 / RK3568 / RV1126 / RV1109 / RK3399 等)| 2026-09 版
eMMC 命令码、EXT_CSD 字段位、寄存器位、Loader 签名算法以 JEDEC eMMC 规范、瑞芯微具体 SDK 文档与 SoC 用户手册为准;本文仅展示排查机制。
- 本文讨论的是瑞芯微主控侧外挂存储的启动 / 烧录失败,与「烧录器找不到型号」是两件事。判别要点:烧录器能正常建工程、能烧、能校验通过,但板子起不来,就是本文范围;烧录器根本选不到型号,请查《烧录找不到型号》系列文档。
- 命令码(CMD0 / CMD1 / CMD2 / CMD3 / CMD7 / CMD8、CMD6 切换 EXT_CSD 等)是 SD/MMC 协议常见写法,并非所有平台与所有器件都一致,动手前逐条核对规范与手册。
- EXT_CSD 的字节偏移、字段位、合法取值、Boot 分区机制、RPMB 鉴权流程全部以 JEDEC JESD84 与平台 TRM 为准,本文只回答「要查哪一类、去哪里查」。
- 涉及RPMB 鉴权写入、Boot 分区使能、安全擦除的操作在多数平台上不可逆或风险极高,见第 8 章与 RPMB 专篇的危险操作提示。
一句话结论:瑞芯微平台上「烧录绿勾但起不来 / 卡在 MaskROM / 报分区或签名错」, 本质是八类根因之一:要么烧录进不去(MaskROM / 下载模式 / 签名)、 要么工程配置对不上(parameter / GPT / 分区)、要么器件状态异常 (eMMC Boot 分区 / EXT_CSD / RPMB / SPI NAND ID)。 烧录器能烧、能校验通过只证明器件是好的、数据是对的, 不证明主控的启动链路能把它认起来——这两者之间隔着整整八类根因。
这份文档解决什么
解决的是瑞芯微 SoC 外挂 SPI NAND 或 eMMC 后,烧录通过但启动失败、卡在 MaskROM、" 报分区 / 签名 / 识别类错误这一类问题的定位与根治方法。全文按 「现象 → 启动链路机制 → 类目 → 立即动作 → 根治动作」组织, 第 9 章是可直接翻查的速查表,第 11 章是可带进车间的核查清单与 FAE 结案栏。
怎么用这份文档
- 先分是烧录进不去还是启动起不来:看串口——连下载模式(Rockusb)都进不去,先查第 1 类;" 能进下载模式但烧完起不来,按第 2~8 类顺位查。
- 抓一份「已知好板」基线:把能正常启动那块板的完整启动日志、parameter.txt、GPT 导出、" EXT_CSD 读值、驱动 ID 表各存一份,后面所有对比都拿它当基准。
- 用启动链四段收敛:MaskROM(下载模式)→ Loader → U-Boot(parameter/GPT)→ Kernel," 故障落在哪一段就翻对应类目,不要跳段。
- 一次只改一个变量:parameter、GPT、EXT_CSD、驱动 ID 表、签名密钥每次只动一处," 改完重新烧录抓日志。
- 用装板实跑闭环:任何改动的最终判定,以「装板跑通完整启动 + 关键功能 + 一次断电重启」为准。
1. 问题本质:瑞芯微启动链路与 MaskROM/Loader 机制
「瑞芯微板子起不来」这句话在现场被用得太泛。它可能下不进 Loader、可能 parameter 报错、 可能 Boot 分区写错、也可能 RPMB 拒写。本章先把现象还原成启动链路: 讲清瑞芯微上电后谁在控制存储、认出器件要满足哪些条件,然后把本文的排查对象与 「烧录器找不到型号」严格切开——这两件事在产线上被混淆的概率极高。
1.1 八类失败沿启动链路定位
现场接到「板子起不来、卡在下载模式、报分区或签名错」,第一件事是按图 1 把问题归到八类之一, 确定断在启动链的哪一段,不要一上来就换料号或重烧。八类对应的是同一条启动链在不同环节断掉的八种暴露方式, 归档的价值在于它直接决定从 s3 到 s8 先翻哪一章。
提醒一:先确认「烧录进得去」还是「启动起不来」。串口若连 Rockusb 下载模式的提示都看不到, 优先第 1 类(下载模式 / 供电 / 线序);若下载模式正常、烧录绿勾,但烧完不能启动,再顺位查第 2~8 类。
提醒二:同一块板可能同时命中多个类目。例如 boot 引脚配错会先让 MaskROM 选错介质, 随后 U-Boot 解析 parameter 也跟着错。类目定的是先查哪一章,不是只查哪一章。
1.2 与「烧录器找不到型号」的分工
这是本文档最重要的一张表。产线上这两件事经常被当成同一件事处理: 「型号不对,让原厂支持一下」。但它们的发生位置、判定主体、根因集合、解决路径完全不同。 判别方法只有一句话:烧录器能不能正常把活干完。
| 维度 | 主控侧 / 启动链路问题(本文) | 烧录器找不到型号(另册) |
|---|---|---|
| 谁在读 | SoC 的 MaskROM / Loader / U-Boot / Kernel | 编程器的算法库与器件支持列表 |
| 发生时机 | 板子上电、烧录后启动、U-Boot 解析阶段 | 烧录工装建工程、选型号时 |
| 典型现象 | 卡 Rockusb、Loader 失败、parameter 报错、unknown id、分区挂载失败 | 烧录软件报「未找到型号」「不支持该 ID」 |
| 判别要点 | 烧录器能正常烧录并校验通过 | 烧录器建不了工程 |
| 根因集合 | 下载模式、parameter、Boot 分区、EXT_CSD、ID 表、签名、GPT、RPMB | 算法库版本、器件支持列表、料号选型 |
| 解决方向 | 改工程 / 改 EXT_CSD / 补 ID 表 / 改签名 / 修 GPT | 升级算法库、申请新型号支持、核对选型 |
| 负责方 | 瑞芯微平台方 + 器件原厂 FAE 一起定位 | 编程器厂商 + 器件原厂 FAE |
烧录器能烧、能校验通过,板子起不来 → 主控侧 / 启动链路问题,看本文。
烧录器建不了工程、选不到型号 → 烧录器侧问题,看《烧录找不到型号》系列。
两者唯一的交叉点:当烧录工具与启动镜像共用同一份「ID → 参数」映射(例如同一 SDK 的器件表被两边引用), 改一侧要连带确认另一侧。
1.3 瑞芯微启动链:MaskROM → Loader → U-Boot → Kernel
瑞芯微 SoC 上电后,真正控制外部存储的实体随时间切换:最早是芯片内部掩膜的
MaskROM(也叫 BootROM),它采样 boot 引脚、按固定顺序尝试各启动介质,并负责把
Loader(idbloader / miniloader)从介质搬进内部 SRAM / DRAM;Loader 初始化内存后加载
U-Boot;U-Boot 解析 parameter.txt 与 GPT 定位分区、加载内核与设备树;
最终进入 Kernel。理解「每一段谁在控制存储」,是定位八类失败的前提。
把「瑞芯微起不来」拆成三个可证伪的命题,逐个排除: ① 烧录进得去吗(第 1 类:下载模式 / Loader 加载)、 ② 工程配置对得上吗(第 2、3、4、7 类:parameter / Boot 分区 / EXT_CSD / GPT)、 ③ 器件被认起来了吗(第 5、6、8 类:SPI NAND ID / 签名 / RPMB)。 任何一例现场问题,都必须先回答这三个问题再动手。
2. 方案总览:SPI NAND 与 eMMC 排查流程
瑞芯微平台上 SPI NAND 与 eMMC 虽然都是「外挂存储」,但排查套路并不完全相同: eMMC 是一条标准 SD/MMC 命令链 + 分区 / Boot 区 / EXT_CSD 的配置世界, SPI NAND 则是「ID 识别 + MTD/UBI + 坏块 / ECC / OOB」的另一套逻辑。 本章先给一张四关收敛图把八类失败框住,再给两张对照表 (介质差异、烧录 / 调试工具),后面六章的所有动作都在某一关内做细分。
2.1 四关收敛:先定关,再翻章
拿到一块起不来的板,不要从第一章顺着读下去,而是先用四关收敛把范围砍小。 每一关只回答一个是非题,判据来源也不同:第一关靠烧录器、第二关靠下载模式握手与 Loader 日志、 第三关靠 U-Boot 报错、第四关靠内核挂载日志。
类目 6(签名不匹配)与类目 1(Loader 加载失败)同属第 ② 关。 签名校验失败的表现就是 Loader 加载不下去,日志可能只报「load loader failed」而不明说签名。 如果第 ② 关答「否」,要同时怀疑这两类,而不是只查供电线序。
2.2 SPI NAND 与 eMMC 的差异对照
「存储」这个词在两类介质上指的不是同一个东西。SPI NAND 的「识别」是一次 SPI 读 ID + 参数页, 坏了靠坏块表与 ECC;eMMC 的「识别」是一整套 CMD 交互 + EXT_CSD,坏了靠 Boot 分区与分区表。 因此「烧错」「认不出」「挂不上」在两类介质上的实现与处置完全不同,不要互相套用。
| 维度 | SPI NAND | eMMC |
|---|---|---|
| 识别方式 | SPI 读 ID(9Fh 等)+ 参数页 / 内部表 | SD/MMC CMD 序列 + CID / CSD / EXT_CSD |
| 关键配置 | 坏块表、ECC 能力、OOB 布局、页 / 块大小 | Boot 分区、EXT_CSD、总线位宽、速率模式 |
| 分区概念 | 无硬件分区,靠文件系统 / 逻辑卷管理 | BOOT0 / BOOT1 / USER 硬件分区 + GPT |
| 烧录入口 | SPI 接口,经 Loader 初始化后写 | MMC 控制器,经 Loader 初始化后写 |
| 高发失败 | ID 未收录、坏块、ECC 不可纠、OOB 错配 | Boot 分区错位、EXT_CSD 错配、GPT 损坏、RPMB 锁 |
| 调试命令 | sf probe / mtd / ubinfo / nand 类 | mmc dev / mmc extcsd read / mmc part |
| 代表料号 | XTX SPI NAND 系列(以数据手册为准) | XT128A 等 XTX eMMC 系列(以数据手册为准) |
2.3 烧录与调试工具
瑞芯微生态下的工具链相对固定,定位时它们各管一段。注意 upgrade_tool 与 AndroidTool 是不同代的工具, 老平台多用 upgrade_tool,新平台(RK356x / RV1126 等)多用 AndroidTool / RKDevInfo; rkImageMaker 负责把镜像拼成可烧写的整体包。工具版本与平台要对应,否则会假绿。
| 工具 | 用途 | 对应阶段 | 备注 |
|---|---|---|---|
| upgrade_tool | 命令行烧录 / 进入 Rockusb 下载模式 | MaskROM → Loader | 老平台常用,命令以所用版本为准 |
| AndroidTool | 图形化烧录与分区管理 | MaskROM → Loader → U-Boot | RK356x / RV1126 等新平台常用 |
| RKDevInfo / rkdevinfo | 读取设备信息与分区状态 | Loader → U-Boot | 用于确认介质与分区是否识别 |
| rkImageMaker | 拼接 / 拆分可烧写整体镜像 | 镜像打包 | parameter 与镜像需版本匹配 |
| 串口终端 | 抓 Rockusb 握手与启动全过程日志 | 全阶段 | 判定「卡在哪一段」的第一手依据 |
| 逻辑分析仪 / 示波器 | 量 boot 引脚、供电、eMMC 信号 | 硬件层 | 下载模式都进不去时必用 |
如果时间只够抓三样,抓这三个:完整启动日志(含 Rockusb 握手与 Loader 加载)、 parameter.txt 与 GPT 导出、好板同位置的 EXT_CSD / eMMC 寄存器读值。 这三样能覆盖第 2~8 章里绝大部分的对比需求。
3. 第 1 类:MaskROM 下 Loader 加载失败 / parameter 版本错误
这一类发生在启动链最上游,比「不认芯片」更早: 串口可能连 Rockusb 下载模式的提示都看不到,或进了下载模式但 Loader 下不去。 它包含两个容易被混淆的子类——Loader 物理上加载失败 (下载模式 / 供电 / 线序 / 镜像损坏)与工程配置对不上 (parameter 版本错)。前者卡在第 ② 关之前,后者卡在第 ③ 关。
3.1 下载模式(Rockusb)都进不去
瑞芯微板子上电后,若所有启动介质都失败,MaskROM 会进入 USB 下载模式等待主机连接。 主机端工具(upgrade_tool / AndroidTool)连不上是最常见的第一道坎。 此时还没到「认不认芯片」,纯粹是「主机到 SoC 的通道」没建立。
- 驱动 / 线序:USB 驱动未装或装错、用的是充电线而非数据线、USB 口供电不足。
- 供电:板子 VCC / VCCQ 不稳,MaskROM 自己还没起来。
- boot 引脚:被强制拉到「不从 USB 启动」的模式,MaskROM 跳过下载模式。
- eMMC / SPI NAND 总线短路:某条信号线对地短路,MaskROM 初始化时被拖死。
工具连不上 → 查通道(驱动 / 线序 / 供电 / 引脚);工具连上了但 Loader 下不去 → 查内容(Loader 镜像 / 签名)。 这两者的处置完全不同,不要一上来就换 Loader 镜像。
3.2 Loader / miniloader 加载失败
通道通了之后,主机把 Loader(idbloader / miniloader) 下载进 SRAM, 由 miniloader 完成 DRAM 初始化,再加载完整 idbloader 并跳转。失败的常见根因:
- Loader 镜像损坏或版本错:与当前 SDK / 平台不匹配,下载即校验失败。
- DRAM 初始化失败:miniloader 里的 DDR 参数与板子内存颗粒不匹配,卡在初始化。
- 签名不匹配(类目 6):开启了安全启动,Loader 哈希 / 密钥不对,拒绝跳转执行。
| 现象 | 可能根因 | 怎么确认 | 处置 |
|---|---|---|---|
| 工具连不上下载模式 | 驱动 / 线序 / 供电 / boot 引脚 | 换线、重装驱动、量供电、量 boot 引脚 | 先恢复通道再谈加载 |
| Loader 下载即失败 | 镜像损坏或版本错 | 比对 SDK 版本与平台型号 | 换对应版本的 Loader |
| 卡在 DRAM 初始化 | DDR 参数与颗粒不匹配 | 看 miniloader 日志 / 用官方参考参数 | 修正 DDR 初始化参数 |
| 下载成功但拒跳转 | 签名不匹配(见类目 6) | 查安全启动开关与密钥 | 对齐签名或关闭安全启动 |
3.3 parameter.txt 版本错误
Loader 起来后会解析 parameter.txt 拿到分区布局与容量声明,
再据此搬运各分区镜像。换料号、换容量、升级 SDK 后若沿用旧 parameter,
就会出现「声明容量 / 分区与实际镜像不匹配」:Loader 解析即报长度错,或把镜像写到错误偏移。
- 容量字段:新料号容量更大却没改,rootfs 分区边界越界。
- 分区偏移 / 长度:镜像实际尺寸变了,parameter 里的 len 没同步。
- FIRMWARE_VER / MACHINE:与镜像头里的版本标记不一致,校验阶段被拒。
| 检查项 | 正确做法 | 怎么确认 | 常见错法 |
|---|---|---|---|
| 容量字段 | 与介质实际容量一致 | 量实际容量并与 parameter 核对 | 换大容量料号没改容量 |
| 分区偏移 | 与镜像实际布局对应 | 导出 GPT / 分区表比对 | 旧偏移套新镜像 |
| 分区长度 | len 不越界、不重叠 | 逐分区算首尾地址 | rootfs 越界写坏邻区 |
| FIRMWARE_VER | 与镜像头版本标记一致 | 读镜像头比对 | 沿用旧版本字符串 |
| MACHINE | 与平台型号一致 | 查平台定义 | 改板后没更新 |
3.4 立即动作与根治动作
| 动作类型 | 具体动作 | 验收标准 |
|---|---|---|
| 立即动作 | 换数据线、重装 USB 驱动,确认工具能枚举到设备 | 设备出现在工具设备列表 |
| 立即动作 | 对比 Loader 版本与当前 SDK / 平台,重下对应 Loader | Loader 下载并跳转成功 |
| 立即动作 | 导出好板的 parameter.txt,与坏板逐字段比对 | 容量 / 分区 / 版本全部一致 |
| 立即动作 | 核对 rootfs 实际大小是否超出 parameter 声明长度 | 无越界、无重叠 |
| 根治动作 | 把 parameter 纳入版本管理,随 SDK / 料号变更评审 | 每次变更有可追溯记录 |
| 根治动作 | 建立「换料号必更新 parameter」的强校验(构建期检查) | 参数与镜像不匹配时构建报错 |
| 根治动作 | 量产工装固定使用「按分区烧写」而非整盘偏移 | 杜绝 Boot 区错位类事故 |
4. 第 2 类:eMMC Boot 分区烧写错位
eMMC 内部有硬件分区:BOOT0、BOOT1、USER、RPMB。 启动代码必须落在 BOOT0 / BOOT1 区,系统镜像落在 USER 区。 这一类失败的典型特征是下载模式正常、烧录绿勾,但板子启动卡在 MaskROM—— 因为 boot 镜像被错误地写到了 USER 区起点,BOOT 区是空的,SoC 从 Boot 区读不到启动头。 根因几乎都是烧录时用了错误的线性偏移。
4.1 eMMC 硬件分区与启动区
eMMC 上电后,SoC 通过 EXT_CSD 的 PARTITION_CONFIG 字段决定从哪个分区启动
(BOOT0 / BOOT1 / USER)。Boot 分区有独立的大小(BOOT_SIZE_MULT),
且写入 Boot 区要走专用切换命令,不能当作 USER 区的线性地址直接写。
理解这一点是避免错位的前提。
| 分区 | 用途 | 烧写方式 | 启动相关 |
|---|---|---|---|
| BOOT0 | 第一启动代码(idbloader / U-Boot) | Boot 分区专用切换命令 | 是,默认首选 |
| BOOT1 | 备份启动代码 | Boot 分区专用切换命令 | 是,PARTITION_CONFIG 可切 |
| USER | 系统镜像 / 根文件系统 / 数据 | 线性地址写 | 可作启动介质(需配置) |
| RPMB | 安全存储(密钥 / 计数) | 鉴权写入,不可随意访问 | 否,但见第 8 章 |
4.2 错位是怎么发生的
错位几乎都来自「整盘线性偏移」思维:有人拿 USER 区的起始地址当 boot 镜像的烧写地址, 于是 boot 镜像被写到 USER 区开头,而 BOOT0 区始终是空的。 烧录工具显示「烧录成功」,是因为它确实把数据写到了指定地址——只是那个地址不是 Boot 区。
不要用「先擦整盘再按固定偏移写」的方式烧 eMMC 启动区。 这种方式极易把 boot 镜像写进 USER 区,且会连带清掉 RPMB 与用户数据。 正确做法是使用烧录工具的「按分区烧写」功能, 让工具自己处理 Boot 区的切换命令与偏移。涉及 RPMB 的清空见第 8 章。
4.3 怎么确认是不是错位
用 rkdevinfo 或 mmc 命令读 Boot 分区使能与内容:
# 进入 U-Boot 或 Loader 命令行后(命令名以所用版本为准)
mmc dev 0 # 选中 eMMC
mmc partconf 0 # 读 PARTITION_CONFIG,确认启动分区
mmc read ${addr} 0x0 0x10 # 读 USER 区起点,看是否误写了 boot 头
# 用专用命令读取 BOOT0 区并确认非空、且偏移与镜像一致
| 检查项 | 正确做法 | 怎么确认 | 错位表现 |
|---|---|---|---|
| Boot 区使能 | PARTITION_CONFIG 指向正确 Boot 区 | 读 PARTITION_CONFIG 字段 | 指向 USER 或空 Boot 区 |
| Boot 区非空 | BOOT0 / BOOT1 写入有效启动头 | 读 Boot 区内容比对 | Boot 区全 0 / 全 FF |
| 烧写方式 | 使用「按分区烧写」 | 查烧录工具工程配置 | 用了整盘线性偏移 |
| 镜像偏移 | 偏移与分区表一致 | 比对 parameter / GPT | boot 头出现在 USER 起点 |
| 启动顺序 | Boot 区优先于 USER | 查平台启动顺序 | 从 USER 读不到启动头 |
4.4 立即动作与根治动作
| 动作类型 | 具体动作 | 验收标准 |
|---|---|---|
| 立即动作 | 用 rkdevinfo / mmc 读 PARTITION_CONFIG 与 Boot 区内容 | 确认 Boot 区非空且偏移正确 |
| 立即动作 | 改用烧录工具的「按分区烧写」重烧 BOOT0 / BOOT1 | Boot 区写入有效启动头 |
| 立即动作 | 对比好板与坏板的 Boot 区前若干扇区 | 内容一致(除版本差异) |
| 立即动作 | 复位后确认从 Boot 区取到启动头 | 启动不再卡在 MaskROM |
| 根治动作 | 量产工程固定「按分区烧写」,禁用裸偏移脚本 | 工程模板不含线性偏移烧写 |
| 根治动作 | 把 Boot 区校验加入首件 SOP(读使能 + 读内容) | 首件报告含 Boot 区比对 |
| 根治动作 | 换料号 / 换容量时复核 Boot 区大小与偏移 | 变更有评审记录 |