全志平台 · SPI NAND / SPI NOR 量产排查
编制日期 2026-09-21 | 版本号 Rev 1.0
XTX 芯天下 · FAE 现场技术文档 | Allwinner 平台外挂 SPI NAND / SPI NOR 量产排查 (BROM → boot0 → U-Boot → kernel)| 2026-09 版
寄存器位、boot pins 状态、sys_config.fex 字段、分区偏移以具体平台 SDK 与对应手册为准;本文仅展示排查机制与常见值。
- 本文讨论的是全志平台外挂 SPI NAND / SPI NOR 的量产启动失败,与「烧录器找不到型号」是两件事:烧录器能绿勾但板子起不来,看本文;烧录器选不到型号,请查《烧录器找不到型号_替代烧录总表》。
- 命令码(如 SPI NOR 9Fh 读 ID、SPI NAND 9Fh/0x9F、eGON 头、SPL 头)与寄存器位是常见写法,并非所有平台/版本一致,动手前逐条核对 SDK 源码与 datasheet。
- 涉及签名、烧断 fuse、改写 boot0 的操作在多数平台不可逆或会让板子变砖,见对应章节的危险操作提示,量产务必先在样品上验证。
- 所有未给出具体数值的参数(分频系数、偏移、容量 ID),一律以具体平台手册与 SDK 源码为准,本文只回答「要查哪一类、去哪里查」。
一句话结论:全志平台 SPI NAND / SPI NOR 量产失败, 99% 发生在启动链路的前两级(BROM 介质识别、boot0/SPL 加载)——而不是烧录器本身。 判别顺序是:先确认 BROM 有没有选对介质、有没有误进 FEL;再看 boot0 镜像头与签名过没过; 最后才是 SPL 的驱动表与分区表。烧录器绿勾只证明「镜像写进去了」,不证明「BROM 认它、boot0 能加载它」。
这份文档解决什么
解决的是全志(Allwinner)系列 SoC 外挂 SPI NAND / SPI NOR 时,量产阶段烧录绿勾却启动失败、 或上电即卡在极早期这一类问题的定位与根治。覆盖 F1C100s / F1C200s / T113 / T113-S3 / R328 / R329 / V851 / V833 / A40i / T507 / H616 等平台,启动链 BROM → boot0(spl) → u-boot → kernel (Linux / Tina / Melis / OpenWrt),烧录工具 PhoenixSuit / LiveSuit / sunxi-fel / 全志量产工具。 全文按「现象 → 机制 → 类目 → 立即动作 → 根治动作」组织,第 9 章是可直接翻查的速查表,第 10 章是防复发清单。
怎么用这份文档
- 先抓完整串口 LOG:从上电第一行到最后一行全量保存,确定卡在 BROM / boot0 / U-Boot / kernel 哪一级。
- 按 8 类根因归档:把现象归到第 3~8 章对应类目,不要一上来就换芯片或重烧。
- 用 4 级断点法收敛:BROM 介质选择 → boot0 头/签名 → SPL 驱动表 → 分区/env,逐级确认。
- 建立「已知好板」基线:把能启动那块板的 LOG、boot pins 电阻、sys_config.fex、分区表、SDK 版本各存一份。
- 一次只改一个变量:boot 电阻、pinmux、签名工具、驱动表、分区表每次只动一处,改完重新上电抓 LOG。
- 用装板实跑闭环:任何改动以「上电跑通完整启动 + 关键功能 + 一次断电重启」为最终判定。
1. 问题本质:全志启动链路与 SPI 控制器
「全志板子起不来」这句话在现场被用得太泛。它可能是 BROM 压根没选对外挂介质, 可能是 boot0 镜像头校验没过被直接丢弃,可能是 SPL 里没有新料号的驱动表, 也可能是 U-Boot 起来了却读不到正确的 env 或分区。本章先把现象还原成机制: 讲清全志的启动链路每一级在干什么、SPI 控制器是怎么把命令送到 XTX 器件的, 然后把本文的排查对象与「烧录器找不到型号」严格切开。
1.1 全志启动链路全景
全志 SoC 上电后,执行顺序是固定的四段:BROM(掩膜 ROM)→ boot0 / SPL → U-Boot → kernel。 每一段都依赖前一段成功地把下一阶段从外挂介质里读出来并校验通过。 任一段失败,系统都会停住或回退(典型是回 FEL 或反复重启)。
统计上,前两段(BROM、boot0/SPL)承担了绝大多数量产启动失败, 因为这两段发生在 DRAM 还没起来的极早期,能用的工具最少、信息也最少。 第三段(U-Boot)和第四段(kernel)失败通常已有串口输出,定位反而容易。 所以本文把 8 类根因里的 6 类都压在前两段,后两段只占 2 类。
1.2 各平台与介质支持概览
全志不同 SoC 的 BROM 对 SPI NAND / SPI NOR 的支持程度、启动介质选择方式都不一样。
下表是常见平台与介质倾向,具体以该平台 SDK 的 sys_config.fex / 设备树与 BROM 支持列表为准。
| 平台 | 典型启动介质 | OS / 固件栈 | 备注(以 SDK 为准) |
|---|---|---|---|
| F1C100s / F1C200s | SPI NOR 为主 | Linux / Melis / 裸机 | 老架构,boot0 与 U-Boot 一体,介质选择较固定 |
| T113 / T113-S3 | SPI NAND / SPI NOR | Tina Linux / Linux | S3 常配 SPI NAND,sys_config 与 dts 双轨 |
| R328 / R329 | SPI NAND / eMMC | Tina Linux / RTOS | RISC-V 协处理器平台,启动链较复杂 |
| V851 / V833 | SPI NAND 为主 | Tina Linux / RTOS | 视觉类 SoC,常用 SPI NAND 做大容量 |
| A40i | SPI NOR / eMMC / NAND | Linux | 车规,启动源多选,boot pins 关键 |
| T507 | SPI NAND / eMMC | Linux / Ubuntu | 工业/车载,分区表偏复杂 |
| H616 | SPI NOR / eMMC | Linux / Android | TV 盒子,常见 SPI NOR 启动 |
1.3 SPI 控制器是怎么把命令送到 XTX 器件的
全志的 SPI 控制器是启动链路里「BROM → 器件」这段的物理通道。 CCU 时钟控制单元先给 SPI 模块提供总线时钟,再经 SPIx_CCR 时钟分频寄存器 得到最终 SCLK;SPIx_TCR 控制主从、模式、片选;数据经 TX/RX FIFO 收发。 引脚必须经过 pinmux 切到 SPI 功能(CS / SCLK / IO0..IO3)才能对外通信。
| 硬件环节 | 控制器 / 寄存器(常见名) | 它决定什么 | 配错的表现 |
|---|---|---|---|
| 时钟来源 | CCU:SPI 总线时钟门控与分频 | SPI 模块有没有时钟、频率档 | BROM 阶段无波形 / 读不到 ID |
| 最终时钟 | SPIx_CCR 时钟分频寄存器 | SCLK 实际频率 | 高频读错、低频正常 |
| 工作模式 | SPIx_TCR 控制寄存器 | 主从 / 单线·双线·四线 / 片选 | 模式不匹配 → 数据错位 |
| 数据传输 | SPIx_TX / RX FIFO | 命令与数据收发 | FIFO 溢出 / 丢字节 |
| 引脚复用 | pinmux(pinctrl / sys_config) | 引脚是否真的在 SPI 功能 | SCLK 上零波形 |
| 片选 | CS# 引脚 + 上拉 | 帧定界 | CS# 浮空 → 概率性失败 |
关键认知:BROM 与 boot0 用的是同一组物理 SPI 引脚。 这意味着如果 pinmux 在第一级就配错,后一级连重新配置的机会都没有—— 这正是「类目 1」最隐蔽的地方。另外,BROM 阶段可用的时钟分频档位有限, 低速下器件才容易识别,所以新料号若对时钟敏感,往往卡在最早期。
1.4 常用工具与命令(常见值)
下面是全志量产排查常用的工具与命令,命令与参数均为常见写法,以实际版本为准。
| 工具 / 命令 | 用途 | 常见值 / 说明 |
|---|---|---|
| PhoenixSuit | Windows 下固件烧录(IMG 包) | 认到设备后烧整包,常见失败在头校验/分区 |
| LiveSuit | 老版本固件烧录工具 | 部分老平台仍用,逻辑同 PhoenixSuit |
| sunxi-fel | FEL 模式下的命令行烧录/调试 | 常见:sunxi-fel ver / spl / write / exec |
| 全志量产工具 | 产线批量烧录与校准 | 含签名、分区、SN 写入等子流程 |
| uboot 命令 | U-Boot 内读 ID / 查分区 | 常见:sf probe / mtd / mmc / printenv |
| 串口 LOG | 唯一能看启动链各阶段的窗口 | 波特率以平台默认为准(常见 115200) |
把启动失败拆成四个可证伪的命题:① BROM 选对介质了吗(第 3 章)、 ② boot0 镜像头/签名过吗(第 4 章)、③ SPL 认得新料号吗(第 5、6 章)、 ④ U-Boot 找得到分区与 env 吗(第 7、8 章)。任何一例现场问题,都必须先回答这四问再动手。
2. 方案总览:失败类别分流
全志平台 SPI NAND / SPI NOR 量产失败看似千奇百怪,但归根结底都能按 「串口 LOG 卡在启动链哪一级」归到 8 个类目、收敛到 4 个排查关卡。 本章先给一张分流图,再给一张介质/平台对比表,后面 6 章的所有动作都是在这张图里选一条往下钻。
2.1 失败类别分流图
拿到一块起不来的板,第一件事是接串口、上电、把从第一行到最后一行全量保存, 然后按下面这张图确定卡在哪一级。绝大多数现场争论(「是芯片坏了还是板子坏了」) 在看到 LOG 第一句之后就消失了。
2.2 介质 / 平台对比:SPI NOR 与 SPI NAND 的启动差异
同一块全志板,挂 SPI NOR 和挂 SPI NAND 的启动路径差异很大: NOR 通常直接从固定偏移读 U-Boot;NAND 要处理坏块跳过与ECC, boot0 必须带坏块表。换介质时最容易漏的就是这一点(见第 5 章类目 4)。
| 维度 | SPI NOR 启动(常见) | SPI NAND 启动(常见) |
|---|---|---|
| BROM 读法 | 固定偏移直接读 U-Boot | 带坏块跳过、按页读,需 ECC |
| boot0 介质分支 | 走 spinor 分支 | 走 spinand 分支(坏块表) |
| 容量 / 偏移 | 偏移固定,容量小(常见 ≤ 256Mbit) | 偏移随坏块浮动,容量大(≥ 1Gbit) |
| 驱动表位置 | U-Boot/Linux SPI NOR 表 | U-Boot/Linux SPI NAND 表(另列) |
| 典型失败 | QE/4B 模式错、ID 未收录 | 坏块门禁、ECC 配错、ID 未收录 |
| sys_config 字段 | storage_type / spinor 相关 | storage_type / spinand 相关 |
不要把「进 FEL」当成「芯片坏了」。进 FEL 是 BROM 的主动行为: 要么你按着 FEL 键上电,要么它确实没找到能启动的介质 / boot0 校验失败。 先按第 3 章类目 2 把 FEL 来源查清楚,再决定是否动芯片。
2.3 四关断点法
与第 1 章的机制对应,量产排查把四关串起来:每一关只回答一个是非题。
| 关卡 | 要回答的问题 | 判据(通过) | 不通过去哪章 |
|---|---|---|---|
| 关卡1 BROM 介质 | BROM 选对启动介质了吗? | boot pins 电平与手册启动表一致,未误进 FEL | 第 3 章 类目1·2 |
| 关卡2 boot0 头/签名 | boot0 镜像头与签名过吗? | eGON/SPL 头校验通过,BROM 正常加载 | 第 4 章 类目3·8 |
| 关卡3 SPL 驱动表 | SPL 认得新料号吗? | 回读 ID 命中驱动表,U-Boot 正常加载 | 第 5·6 章 类目4·5 |
| 关卡4 分区 / env | U-Boot 找得到分区与 env 吗? | 分区表与镜像一致,env 生效 | 第 7·8 章 类目6·7 |
3. 类目 1·2:BROM 介质识别失败 / FEL 误触发
这两类都发生在启动链最早期(BROM 阶段),是信息最少、工具最少、却最高发的类。 它们的共同表现是「串口几乎一行不出」,区别是:类目 1 是 BROM 选错了介质(boot pins / pinmux 错), 类目 2 是 BROM 主动放弃、转进 FEL。先分清这两类,后面才不会在错误的方向上耗时间。
3.1 类目1:BROM 无法识别外挂介质
BROM 是掩膜在 SoC 里的第一段代码,它上电后先采样 boot pins, 根据电平决定去哪个介质找启动代码,再通过 SPI 控制器把 boot0 读进来。 这条链路上有两处最常断:
- boot pins 配错:上下拉电阻焊错、被其它电路拉偏,导致 BROM 选成 SPI NOR 去读 SPI NAND(或反之)。
- SPI 引脚复用错:pinctrl / sys_config 里这几个引脚没切到 SPI 功能, BROM 阶段就发不出波形(因为 BROM 用的也是这组物理引脚,没机会在后面修正)。
| 检查项 | 要求(以手册为准) | 怎么确认 | 不合规后果 |
|---|---|---|---|
| boot pins 电平 | 复位期间各引脚电平与启动模式表一致 | 万用表量复位瞬间电平 | 选错启动介质,ID 对不上 |
| 上下拉电阻 | 阻值与原理图、手册建议一致 | 断电量阻值并查 net 连接 | 电平漂移到临界,温度相关失效 |
| SPI 引脚复用 | BROM 阶段引脚已切到 SPI 功能 | dump 复用寄存器 / 看波形 | SCLK 零波形,全无应答 |
| CS# 上拉 | 复位期间稳定为高,避免误触发 | 复位期间单次触发抓 CS# | 随机命令,概率性失败 |
| FEL 键 GPIO | 未被意外拉低(默认上拉) | 量 FEL 键引脚电平 | 每次上电都进 FEL |
| 电源域 | SPI IO 域电压与器件 VCC 一致 | 量实际电压 | 幅度超标,完全不响应 |
3.2 类目2:FEL 模式被误触发
FEL 是全志的 USB 下载模式。正常量产不应该进 FEL——它只在两种情况下出现: 用户按住了 FEL 键(特定 GPIO 被拉低),或者 BROM 找不到有效启动介质 / boot0 校验失败而主动回退。 现场常把「进 FEL」误判成「芯片坏了」,反复换料,其实板子一直在等你插 USB。
- 看串口:进 FEL 时串口通常只有极少数字符或干脆没有;
- 看 PC 设备管理器:会出现一个新的 USB 设备(常见为全志 USB 或大容量设备);
- 用 sunxi-fel 探一下:
sunxi-fel ver能返回 SoC 信息即确认在 FEL 模式; - 区分来源:拔掉 FEL 键重新上电还进 FEL,说明是 boot0 / 介质问题(转第 4 章),不是按键。
3.3 立即动作与根治动作
| 动作类型 | 具体动作 | 验收标准 |
|---|---|---|
| 立即动作 | 量复位期间 boot pins 电平,与手册启动表逐位比对 | 电平组合落在目标介质档 |
| 立即动作 | 逻辑分析仪挂 SCLK,确认上电后有没有方波 | 能看到干净的命令帧 |
| 立即动作 | 拔掉 FEL 键重新上电,确认是否还进 FEL | 正常启动则原因为 FEL 键 |
| 立即动作 | dump SPI 引脚复用寄存器,确认在 SPI 功能 | 功能编码与手册一致 |
| 根治动作 | boot 电阻上下拉纳入原理图评审清单 | 评审记录有时序/电平核对项 |
| 根治动作 | FEL 键引脚在试产首件中固定测量并存档 | 首件报告附电平结论 |
| 根治动作 | pinctrl / sys_config 复用随 SDK 版本评审 | 复用表可追溯 |
不要用「短接 FEL 键引脚试试」来定位:带电短接可能损伤 GPIO 或电源域。 确认 FEL 键对应的 GPIO 与上下拉电阻后,用断开/恢复上拉的方式在断电状态下验证。 涉及 boot pins 的修改要断电后改电阻,改完先量电平再上电。
4. 类目 3·8:boot0 签名失败 / eGON 与 SPL 头校验失败
这两类都发生在 BROM 加载 boot0 的那一步,表现高度相似:烧录器绿勾(镜像写进去了), 但 BROM 就是不加载,串口停在极早期。区别是:类目 3 是「签名工具与 u-boot 不匹配」让签名校验过不了; 类目 8 是「eGON 头部或 SPL 头部本身算错」让头校验过不了。两者都属于「镜像文件问题」,不是器件问题。
4.1 类目3:boot0 镜像签名失败或校验错
量产固件通常带签名:BROM 在加载 boot0 前会用内置公钥做签名校验(常见 RSA / ECDSA,以 SDK 为准)。 签名工具、u-boot 版本、公钥必须三者配套。现场最常见的错法是: 升级了 u-boot,却沿用了旧签名工具,或换了一套不匹配的密钥,于是 BROM 校验直接失败。
| 检查项 | 要求(以 SDK 为准) | 怎么确认 | 不匹配后果 |
|---|---|---|---|
| 签名工具版本 | 与 u-boot / boot0 同源同版本 | 比对打包脚本与 SDK 版本号 | 公钥校验失败,丢弃镜像 |
| 密钥 / 证书 | 公钥与签名私钥配套 | 确认所用 key 与烧录公钥一致 | 签名验证不通过 |
| u-boot 版本 | 与签名时的 u-boot 一致 | 查版本字符串 / git 提交 | 内容变了,签名对不上 |
| secure boot 开关 | 开启/关闭状态与镜像预期一致 | 查 eFUSE / OTP 配置 | 开了却没签名 → 必挂 |
| 打包流程 | 走平台官方打包,不手工改头 | 用官方 pack 工具重新生成 | 手工改头易算错 CRC |
4.2 类目8:eGON 头部与 SPL 头部校验失败
全志镜像有固定的头部结构:外层是 eGON.BT0 头(含 magic、长度、平台标识等), 内层是 SPL 头(含 CRC、长度等)。BROM 先校验 eGON 头,再校验 SPL 头, 任何一处算错(长度填错、CRC 算错、平台标识不对)都会被判为非法镜像被丢弃。
| 头部 | 关键字段(常见) | 算错的表现 | 怎么确认 |
|---|---|---|---|
| eGON.BT0 | magic / 总长度 / 平台标识 | BROM 读头即判非法 | 用工具 dump 头部逐字段比对 |
| SPL 头 | CRC / 数据长度 / 入口 | CRC 不符 → 丢弃 | 重新算 CRC 与镜像比对 |
| 长度字段 | 必须与实际镜像字节数一致 | 长度不符 → 截断/拒绝 | 量实际文件大小 |
| 平台标识 | 必须匹配目标 SoC | 标识错 → 不加载 | 查镜像头平台码 |
两者都卡在 BROM 读 boot0 那一步,但失败环节不同: 类目 8 往往在「头校验」阶段就挂(eGON/SPL 头本身坏), 类目 3 是头没问题、签名那一步挂(公钥/密钥/工具不匹配)。 能用打包工具重新生成一份「头+签名都自洽」的镜像来区分——重新生成后好了就是类目 3, 仍然失败则偏向类目 8 或镜像打包本身有误。
4.3 立即动作与根治动作
| 动作类型 | 具体动作 | 验收标准 |
|---|---|---|
| 立即动作 | 用同版本打包工具重新生成 boot0 镜像并比对头 | 新镜像头字段自洽 |
| 立即动作 | 确认签名工具、u-boot、公钥三者版本一致 | 签名校验通过 |
| 立即动作 | dump 坏镜像的 eGON/SPL 头,逐字段比对好镜像 | 定位是哪个字段算错 |
| 立即动作 | 单板用 sunxi-fel 直接灌一份已知好 boot0 验证链路 | 能加载说明是镜像问题 |
| 根治动作 | 把打包/签名工具与 SDK 版本绑定管理 | 升级有迹可循 |
| 根治动作 | 量产包来源做哈希校验,防传输损坏 | 每包可验证完整性 |
| 根治动作 | secure boot 方案保留可回退密钥 | 异常可恢复 |
不要为了「能启动」而关闭签名校验或烧断安全 fuse。 关闭校验会让板子暴露在被刷恶意镜像的风险里;烧断 fuse(如启用 secure boot 后)往往不可逆, 会让该芯片再也无法用旧方式启动。量产务必先在样品上验证,并保留可回退的密钥方案。