只读分享解决方案文档调试&解决方案📅 2026-09-21🔖 Rev 1.0⏳ 29天有效(至 2026-10-31)
🔧解决方案&应用市场分析 -> 调试&解决方案 -> 存储_量产问题排查 -> 海思平台_SPI_NAND_量产常见失败_量产排查

海思平台_SPI_NAND_量产常见失败_量产排查

生成时间 2026-09-28 13:34:52 有效期至 2026-10-31 23:59:59(29天有效(至 2026-10-31))
同系列 · 调试&解决方案

海思平台 · SPI NAND 量产常见失败排查

编制日期 2026-09-21 | 版本号 Rev 1.0

XTX 芯天下 · FAE 现场技术文档 | 海思 Hi35xx / Hi38xx / Hi3516 / Hi3559 等 SoC 外挂 SPI NAND 量产失败(启动 / 烧录 / 分区 / 挂载)| 2026-09 版

技术事实核查纪律(执行前必读)

寄存器位、ECC 强度、坏块策略、分区偏移、命令码以海思 SDK 与具体料号 datasheet 为准;本文只展示排查机制。

  • 本文讨论的是海思主控侧外挂 SPI NAND 读不出来 / 起不来,与「烧录器找不到型号」是两件事。判别要点:烧录器能正常建工程、能烧、能校验通过,但板子起不来,就是本文范围;烧录器根本选不到型号,请查烧录器侧替代总表专册。
  • 命令码(9Fh 读 JEDEC ID、06h 写使能、0Bh 读、13h 页读等)是 SPI NAND 的常见写法,并非所有器件与所有平台都一致,动手前逐条核对 datasheet。
  • 厂商 ID、ECC 能力、OOB 布局、坏块策略全部以具体料号 datasheet 与海思 SDK 源码为准,文中标注「常见值」的必须以 datasheet 复核,不确定的不写。
  • 涉及全片擦除 / 写保护解除 / OTP 改写的操作在多数平台不可逆或影响良率,产线执行前必须经过 FAE 与产品方双签。
7 类
量产失败根因归类
ID 未收录 · ECC/OOB · 坏块策略 · 分区错位 · UBI · 假通过 · 批次
3 段
启动链路必过关卡
BootROM 识别 → u-boot 加载 → kernel 挂载,逐段断点
9Fh
读 JEDEC ID 的常见命令码
命令码与返回字节数以具体料号 datasheet 为准
1 份
必须锁定的参数卡
SDK 版本 / 分区表 / ECC 强度 / 坏块策略,烧录工程与之一致
金样对照
区分板级与存储问题
同板换认可料 / 问题料上金板,先定位是哪一侧

一句话结论:海思平台 SPI NAND 「烧录绿勾却起不来 / 启动报错」绝大多数是 烧录侧与主控侧对器件的「认知不一致」——ID 表没收录、ECC/OOB 解释不同、坏块策略错位、分区版本不对、UBI 几何不一致。 烧录器能烧、能校验通过,只证明器件是好的、数据写进去了;不证明海思控制器能按同一套规则把它读出来。 先抓完整启动 LOG 按关键字分流,再逐类对齐参数卡。

这份文档解决什么

解决的是海思 SoC 外挂 SPI NAND 在量产阶段「绿勾后启动失败 / 启动中途报错」这一类问题的定位与根治, 覆盖 Hi35xx、Hi38xx、Hi3516、Hi3559 等系列从 BootROM → u-boot → kernel(LiteOS / OpenHarmony / Linux)整条链路。 全文按「现象 → 机制 → 类目 → 立即动作 → 根治动作」组织,第 9 章是可翻查的速查表,第 10 章是防复发的参数卡与首件检验。

第 1 类
SPI NAND ID 未收录
海思 SDK 的 spi-nand 器件表(drivers/mtd/nand/spi/)没有该 XTX 料号,BootROM / u-boot 读回 ID 后查表未命中,报 unknown ID。补驱动表或打原厂补丁即可,器件本身往往是好的。
高发:换料号没同步更新 SDK 器件表
第 2 类
ECC 与 OOB 布局不一致
烧录器写 OOB 时按自己的 ECC 强度 / 布局落盘,海思 NAND 控制器按另一套解释 OOB,两者对不上。表现为主控读到 ECC error 或数据错位,烧录器侧却一切正常。
高发:烧录器与 SDK 用不同 ECC 配置
第 3 类
坏块表策略不一致
烧录器「跳过坏块、逻辑连续」搬数据,BootROM 按物理块 + 自带 BBT 直读,同一逻辑地址指向不同物理块。结果是启动代码读到的不是烧录时被写入的那一页。
高发:烧录端 BBT 与 BootROM BBT 位置不同
第 4 类
分区表版本与镜像错位
mtdparts / bootargs 里的分区偏移与烧录镜像实际落盘偏移不是同一版,内核去错的位置找 rootfs。常见于 SDK 升级后分区改了、烧录工程没跟着改。
高发:SDK 升级后分区表未同步烧录工程
第 5 类
UBI / UBIFS 挂载失败
EC header 损坏、UBI 卷与镜像不匹配、PEB 数与参数不符、ECC 导致 PEB 读坏,kernel 在 ubi_attach 后挂不上根文件。多发生在 kernel 阶段,能进命令行却起不来。
高发:UBI 镜像与控制器几何参数不一致
第 6/7 类
假通过 / 仅新批次失败
烧录器 verify 按自己的读回比绿勾,但主控按逻辑地址 + 坏块映射读到的内容错位(假通过);或同料号新批次才失败,指向批次参数页 / 配置位差异,需转批次差异专篇。
高发:只信烧录器绿勾 / 忽略批次差异

怎么用这份文档

  1. 先抓一份完整启动 LOG:从按下上电到卡住的全部串口输出贴出来,按第 2 章关键字把失败归到某一类,不要一上来就换芯片。
  2. 存一份「已知好板」基线:把能正常启动那块板的启动日志、回读 ID、烧录工程参数、分区表各存一份,后面所有对比都拿它当基准。
  3. 用第 1 章的三段断点法收敛:先确认 BootROM 是否读到 ID,再看 u-boot 是否校验过镜像,最后看 kernel 是否挂上 UBIFS——不要跳段。
  4. 一次只改一个变量:SDK 器件表、ECC 强度、坏块策略、分区偏移每次只动一处,改完重新烧录 + 上电抓日志。
  5. 金样对照闭环:同板换认可料一次、问题料上金板一次,确认是板级还是存储侧,再决定改烧录还是改 SDK。
  6. 终判以装板实跑为准:任何改动的最终判定,是「完整启动 + 关键功能 + 一次断电重启」都通过,烧录器绿勾不能替代。
FAE 现场最常见的三个开场

开场一:「烧录器都绿勾了,板子死活起不来」——这一类九成落在第 2/3/4 类(ECC/OOB、坏块策略、分区错位),或第 6 类假通过。先抓 LOG,不要怀疑烧录器坏了。

开场二:「昨天还好好的,今天整批起不来」——先看是不是 SDK / 烧录工程被人改过(版本漂移,第 4 类),再看是不是默默换了批次(第 7 类)。先用参数卡比对昨天与今天的差异。

开场三:「有的板能启、有的不能,同一批里随机」——坏块策略不一致(第 3 类)或单板电源 / 焊接最可疑。先用烧录器扫坏块数,把「有坏块」和「板级虚焊」分开。

阅读约定

全文把「烧录侧」与「主控侧」当成两个独立视角反复对比——这是 SPI NAND 量产失败的真正源头。 凡是结论里出现具体数值(厂商 ID、ECC 强度、坏块标记位、分区偏移),一律以具体料号 datasheet 与海思 SDK 源码复核; 本文只回答「要查哪一类、去哪里查、怎么对齐」,不替代原厂文档。

本文不覆盖的范围
  • 板级供电 / 复位 / 时钟 / boot pin / 焊接虚焊:这些会伪装成「不认芯片」,但归硬件,不在本文 7 类。
  • 烧录器根本选不到型号:那是烧录器侧算法库问题,查《烧录器找不到型号_替代烧录总表》专册。
  • 精确数值:寄存器位域、ECC 能力、OOB 字节数的精确值以海思 SDK 与 XTX datasheet 为准,本文只给排查框架。
向 XTX FAE 求助时请带齐
  • 完整启动 LOG(上电到卡住,不要只截最后一行);
  • 回读的 ID 字节 + 参数页(或关键寄存器读回);
  • 当前 SDK 版本 / 补丁号 / 烧录工程版本 / 分区表版本;
  • 料号 + 批次号 + 失败率 + 是否含坏块 + 同板换料结果。

1. 问题本质:海思侧启动链路与识别机制

海思平台「烧录绿勾却起不来」这句话在现场被用得太泛。它可能是 BootROM 根本没读到 ID, 可能是 u-boot 读到了但 ECC 校验不过,也可能是 kernel 进去了却挂不上 UBIFS。 本章先把现象还原成机制:讲清海思是怎么把一颗 SPI NAND 从 BootROM 一路认到 kernel 的、 每一段失败会暴露成什么长相,然后把本文的排查对象与「烧录器找不到型号」严格切开。

1.1 三段启动链路

海思 SoC 外挂 SPI NAND 的启动是一条串行链路:BootROM 先把最前面的 SPL 搬进内部 SRAM, SPL / u-boot 再去扫整片 NAND、加载环境变量与内核镜像,kernel 最后挂载 UBIFS 跑应用。 每一段都要重新和 SPI NAND 打一次交道,任何一段对器件的「认知」和烧录时不一致,整条链就断。

海思上电启动链路:SPI NAND 在 BootROM / u-boot / kernel 三段都要被重新识别BootROM发 9Fh 读 ID匹配器件表搬 SPL 到 SRAMu-boot / SPL扫 SPI NAND加载 env / 分区校验镜像签名kernelLiteOS / OH / Linux挂载 UBIFS启动应用ID 未收录常在此暴露ECC / OOB 多在此暴露UBI 挂载在 kernel 暴露断链规律· 任一段对 SPI NAND 的识别失败,整条启动链都会断;失败「长相」取决于断在哪一段。· BootROM 读不到 ID → 连 SPL 都搬不起来(最常见 unknown ID);u-boot 阶段 ECC/OOB 不一致 → 镜像校验失败。· kernel 阶段坏块 / 分区 / UBI 错位 → 能进 kernel 但挂不上根文件系统(mount 失败 / panic)。
图 1 · 海思上电启动链路与 SPI NAND 识别节点
断链位置决定失败长相

BootROM 段断 → 连第一条启动打印都可能没有,或报 unknown ID / No SPI NAND, SPL 根本搬不起来;u-boot 段断 → 能进 u-boot 但加载内核时 ECC error / 镜像校验失败; kernel 段断 → 能进命令行甚至能看 log,但 ubi_attach 后挂载根文件失败、内核 panic。

1.2 海思怎么「认」一颗 SPI NAND

海思对 SPI NAND 的识别,本质是一次 「发命令 → 收结构化应答 → 查表 → 套参数」的过程:

  • 读 ID:BootROM / 驱动发 9Fh(写使能 06h 后),器件回出 [厂商ID | 器件ID | 容量ID] 一串字节;
  • 查表:把回读的 ID 拿去 SDK 的 spi-nand 器件表 (drivers/mtd/nand/spi/ 下)逐条匹配;
  • 套参数:命中后把表里登记的页大小、OOB 大小、ECC 强度、坏块处理方式填进控制器结构体;
  • 后续操作:之后所有读页(13h)、读数据(0Bh)、写、擦都按这套参数走。
识别步骤海思做了什么失败时的可观测现象对应类目
① 供电与时钟给 SPI NAND 上电、等 VCC/VCCQ 稳定、开 SPI 控制器时钟完全静默、电流异常(属板级电源,见纪律)
② 发 9Fh 读 IDCS# 拉低送读 ID 命令,器件同帧回出 ID 字节回读 ff ff ff 或 00 00 00第 1 类(ID 未收录)
③ 查器件表用回读 ID 去 drivers/mtd/nand/spi/ 器件表匹配unknown id / unrecognized第 1 类(ID 未收录)
④ 套几何参数填页大小 / OOB / ECC 强度进控制器型号打印对但读 ECC error第 2 类(ECC/OOB)
⑤ 坏块处理按 BBT 策略决定读哪个物理块读到的内容错位 / 跳坏第 3 类(坏块策略)
⑥ 加载与挂载u-boot 校验镜像、kernel 挂 UBIFS校验失败 / mount 失败第 4、5 类

关键认知在于:ID 对,不代表参数对。ID 只是查表的键,真正决定能不能读的是查表之后套上来的那一组参数 (页 / OOB 大小、ECC 强度、坏块策略)。这正是本文 7 类失败里 2~5 类全部来自「参数认知不一致」的根本原因。

1.3 与「烧录器找不到型号」的分工

产线上这两件事经常被当成同一件事处理,但发生位置、判定主体、根因集合、解决路径完全不同。 判别只有一句话:烧录器能不能正常把活干完。

维度主控侧起不来(本文)烧录器找不到型号(另册)
谁在读海思 BootROM / SPL / u-boot / kernel 驱动编程器算法库与器件支持列表
发生时机板子上电、启动各阶段初始化时烧录工装建工程、选型号时
典型现象unknown ID、ECC error、mount 失败、起不来烧录软件报「未找到型号」「不支持该 ID」
判别要点烧录器能正常烧录并校验通过烧录器建不了工程
根因集合ID 表、ECC/OOB、坏块策略、分区、UBI算法库版本、器件支持列表、料号选型
解决方向改 SDK 器件表 / 对齐烧录参数 / 改分区升级算法库、申请新型号支持
负责方海思平台方 + XTX FAE 一起定位编程器厂商 + XTX FAE
一句话判别

烧录器能烧、能校验通过,板子起不来 → 主控侧问题,看本文。
烧录器建不了工程、选不到型号 → 烧录器侧问题,看替代烧录总表专册。

两者唯一的交叉点:当烧录器与海思 SDK 共用同一份「ID → 参数」映射时(同一颗料号两套工程都引用),改一侧要连带确认另一侧。

1.4 先抓 LOG 再动参数

无论归到哪一类,现场第一步永远是接串口、上电、把从按下复位到卡住的完整 LOG 存下来。 海思平台在不同阶段会打出不同关键字(SPI NAND、unknown id、ECC、 ubi、bad block),这些关键字是第 2 章分流的直接依据。 没有完整 LOG 就改烧录参数,等于盲调——很可能把 5 分钟能定位的问题拖成两天的拉锯。

1.5 海思各系列外挂 SPI NAND 的差异

海思 Hi35xx / Hi38xx / Hi3516 / Hi3559 等系列都支持外挂 SPI NAND,但具体谁先启动、SPI NAND 扮演什么角色、BootROM 如何找它因系列与具体型号而异。 排查前先确认你手上是哪个系列、SPI NAND 是主启动介质还是辅助介质,否则 boot pins 与器件表的核对方向会搞反。

系列(举例)常见启动介质SPI NAND 的典型角色排查注意
Hi35xx(多媒体)SPI NAND / eMMC / NAND小容量固件 + 配置分区以具体型号硬件指南为准
Hi38xx(安防)SPI NAND / eMMC常作主启动介质以具体型号硬件指南为准
Hi3516(AI 相机)SPI NAND / eMMC常作主启动介质以具体型号硬件指南为准
Hi3559(高端视觉)SPI NAND / eMMC / SD固件 + 算法分区以具体型号硬件指南为准

注意上表是常见定位的归纳,不是承诺:同一系列不同型号、同一型号不同项目,启动介质选择都可能不同。 最终以该板《硬件设计指南》的 boot 配置与 SDK 的 defconfig 为准。本文所有机制不依赖具体系列,但第 3 章「加器件表项」时必须按你这个系列的驱动路径去加。

1.6 海思 SPI NAND 控制器的 ECC 配置落在哪

海思 NAND 控制器把 ECC 强度、step size、纠错开关等放在一组控制器寄存器里, 具体寄存器名与位域因系列与 SDK 而异,以海思 TRM 与 SDK 源码为准。排查第 2 类时, 先在 SDK 里确认 nand-ecc-strength / nand-ecc-step-size 这两个关键参数—— 它们就是控制器与烧录器必须对齐的「ECC 契约」。

现场只核对两个旋钮就够了

不必通读寄存器手册。只要确认「SDK 的 ECC 强度 / step」与「烧录工程的 ECC 强度 / step」完全一致, 第 2 类大概率就关掉了。其余位域(随机化、片内 ECC 使能等)只在更隐蔽的个案里才需要动, 届时按本文纪律去查对应 SDK 源码。

1.7 为什么 SPI NAND 比 NOR 更容易在量产翻车

SPI NOR 没有坏块、没有 OOB/ECC 之争,烧录器与主控看到的是同一片线性空间,参数不一致几乎无从发生。 SPI NAND 把坏块、OOB、ECC、BBT 全部暴露给主控和烧录器, 两边只要有一处默认假设不同,量产就会被放大成「绿勾不启」。这也是本文 7 类失败几乎都集中在 SPI NAND 的原因—— NOR / eMMC 没有这套暴露面,问题天然少一个数量级。

1.8 关键术语速查

第七章反复出现几个术语,先统一叫法,避免现场各说各话:

  • OOB(Out-Of-Band):每页数据之外的小块区,存 ECC 校验码、坏块标记、spare;布局必须两侧一致。
  • BBT(Bad Block Table):坏块映射表,记录哪些块不可用;烧录器与 BootROM 的策略必须一致。
  • ECC:纠错码,强度(bit 数)与 step size 决定能纠多少位错;强度两侧必须相同。
  • 逻辑地址 / 物理地址:逻辑是「跳过坏块后连续」的视图,物理是器件真实块号;坏块策略不同会让二者错位。
  • PEB / LEB:UBI 的物理擦除块 / 逻辑擦除块,体积差一个 EC header,配置须与 SDK 一致。
一句话机制

把「海思起不来」拆成三个可证伪的命题逐个排除: ① BootROM 读到 ID 没(第 3 类)、 ② u-boot 按什么 ECC / 坏块规则读(第 4、5 类)、 ③ kernel 的分区 / UBI 与烧录镜像一致没(第 6、7 类)。 任何一例现场问题,都必须先回答这三个问题再动手。

2. 方案总览:分流与介质对比

海量失败现象背后,真正要做的动作其实很收敛:读 LOG、定类目、对齐参数卡。 本章给出一张分流图(按关键字直接落到第 3~8 章)和一张介质对比表(说明为什么本文聚焦 SPI NAND 而不套用 NOR / eMMC 的套路)。

2.1 分流总图

现场不要凭感觉改参数。先把完整启动 LOG 抓下来,按下面的关键字把失败归到对应章节,再去翻那一章的「立即动作」。

量产失败分流:先抓 LOG,再按关键字进对应章节① 抓完整启动 LOG(上电 → 卡住)② 比对 SDK 是否收录料号 ID③ 核对烧录工程:算法/坏块/ECC/分区④ 金样板 + 问题料交叉验证按 LOG 关键字分流到对应章节unknown ID / No SPI NAND→ 第 3 章(ID 未收录)ECC error / uncorrectable→ 第 4 章(ECC / OOB)bad block / BBT mismatch→ 第 5 章(坏块策略)partition / offset 错位→ 第 6 章(分区错位)ubi_attach / mount 失败→ 第 7 章(UBI 挂载)verify 过仍不启→ 第 8 章(假通过)仅新批次失败→ 第 8 章(批次差异)
图 2 · 按启动 LOG 关键字分流到对应章节
分流的两句口诀

有 ID 但读错 → 第 4/5/6/7 章(参数认知不一致,不缺驱动,缺参数对齐); 连 ID 都读不到 / 读不对 → 第 3 章(器件表没收录)或板级接线电源(见纪律篇)。

2.2 介质对比:为什么 SPI NAND 要单独立章

海思外挂存储常见四种介质,识别依据与失败长相差别很大,排查套路不能互相套。本文聚焦 SPI NAND, 因为它同时具备「JEDEC ID + 参数页 / 内建几何 + OOB/ECC + 坏块管理 + UBI」五重复杂度,失败类目最多。

介质识别依据坏块 / OOB常见失败长相本文比重
SPI NANDJEDEC ID + 参数页 / 内建几何暴露给主控,需自管坏块 / OOB / ECCunknown ID、ECC error、mount 失败全文主战场
SPI NORJEDEC ID(+ SFDP)无坏块、无 OOBunknown id、SFDP 解析错另册(NOR 专篇)
eMMCCMD1 OCR / CMD2 CID / EXT_CSD器件内部透明管理坏块总线宽度 / 速率 / 分区配置错另册(eMMC 专篇)
Raw NAND(并口)ONFI / 参数页暴露坏块 / OOB,但并口总线接线 / 时序为主本文不展开
不要跨介质套结论

SPI NOR 没有坏块、没有 OOB/ECC 布局之争;eMMC 的坏块由器件内部透明管理,主控只看到逻辑块。 只有 SPI NAND 把坏块、OOB、ECC、BBT 全部暴露给主控和烧录器, 所以「烧录侧与主控侧认知不一致」在 SPI NAND 上最容易发生,也是本文 7 类失败的主战场。

2.3 核心动作:对齐三件套

无论归到哪一类,最终都收敛为同一件事——让烧录工程与海思 SDK对三件套达成一致:

  • ID 表:SDK 的 spi-nand 器件表包含该 XTX 料号,且参数正确;
  • 分区:mtdparts / bootargs 的分区偏移与烧录镜像落盘偏移是同一版本;
  • ECC / 坏块:烧录器的 ECC 强度、OOB 布局、坏块跳过策略与海思 NAND 控制器一致。

三件套锁进参数卡(见第 10 章),量产才有可复现的基线。

2.4 海思烧录工具链(HiTool / hiburn)与参数一致性

海思量产常用 HiTool(Windows 图形工具)或 hiburn / 一线烧录方式把镜像写到外挂 SPI NAND。 这些工具本身不「认识」器件参数——ECC 强度、OOB 布局、坏块策略、分区偏移全部来自你导入的那份烧录工程 / XML 配置, 也就是第 3~6 章三件套的落点。工具报绿勾,只代表「按这份工程把活干完了」,绝不代表工程里的参数与海思 SDK 一致。

  • 工程即参数:HiTool 工程里的「器件类型 / 页大小 / OOB / ECC / 坏块策略」选项,就是第 2 类与第 3 类失败的开关,改动前先对照参数卡。
  • 一线烧录 vs 座烧:在板一线烧录受板级走线 / 电平影响,座烧不受;若座烧 OK、一线烧失败,先怀疑板级(纪律篇)而非参数。
  • 版本一致性:HiTool 工程版本、SDK 版本、烧录器算法库版本要写在同一张参数卡上,避免「换电脑就换行为」。
工具绿勾 ≠ 参数正确

在板用 HiTool 烧完绿勾,和「主控能按同一套规则读出来」是两件事。本文 7 类失败里,第 2、3、4、6 类都可能在工具绿勾的掩护下发生, 所以第 8 章强调:验收必须包含装板实跑 + 关键区逻辑地址读回,不能只看工具绿勾。

2.5 样例启动 LOG 解读

下面是一段示意启动 LOG,标注了第 2 章分流会用到的关键字。真实 LOG 以你的平台与 SDK 为准,不要逐字对照。

# BootROM 阶段
SPI NAND: unknown id (0b 21 00)        # ← 第 1 类:器件表未收录
# u-boot 阶段
Loading Environment from SPI NAND ...
ubi: reading page 0x10 ... ECC error     # ← 第 2 类:ECC / OOB 不一致
# kernel 阶段
ubi_attach: bad EC header at PEB 12     # ← 第 5 类(上游多为第 2 类)
VFS: Cannot open root device "ubi0"     # ← 第 4 / 5 类:分区或 UBI 错位
Kernel panic - not syncing              # ← 最终表现(线索在上面)
看 LOG 的顺序

从第一段 BootROM 往下读,第一处报错通常就是根因所在段;它之后的报错多是连锁反应。 不要被最后一行 Kernel panic 吓到,真正的线索在它前面第一段失败处。

2.6 烧录侧与主控侧视角对照小结

一句话记住两边视角

烧录器关心「写得进、读得出(烧录器自己读)」;主控关心「按逻辑地址 + 坏块映射能读出来」。 本文 7 类失败,本质都是这两套「写得进 / 读得出」的规则没对齐。凡是绿勾不启,先问一句: 「主控侧的读规则是什么、和烧录器一致吗?」

3. 第 1 类:SPI NAND ID 未收录

现象:烧录器一切正常(能建工程、能烧、能校验通过),但板子上电后 BootROM / u-boot 报 unknown ID、No SPI NAND、unrecognized JEDEC id。 根因几乎总是海思 SDK 的 spi-nand 器件表没有这个 XTX 料号——器件是好的,只是主控的「花名册」里没它。

3.1 原理

海思读 ID 后,会用回读的 [MID|DID|容量] 去 drivers/mtd/nand/spi/ 下的器件表逐条匹配。 命中了才把页大小、OOB、ECC、坏块策略套进来;没命中就退回默认参数或直接放弃,表现成 unknown ID。 换料号(如新导入 XT25Q08D)却没同步更新 SDK 器件表,是这一类最高发的触发动作。

第 1 类机制:9Fh 读回 ID,但 SDK 器件表没有这一项 → unknown ID读 ID 链路(9Fh)① 主控发 06h 写使能 → 发 9Fh② SPI NAND 回 [MID|DID|容量]厂商 ID(MID)常见值以具体料号 datasheet 为准如 0x0B / 0x21 / 0x48 仅为示意,非承诺参数SDK 器件表(drivers/mtd/nand/spi/)XT25F08B → 0x0B 0x21 ... ✓XT26G01B → 0x0B 0x22 ... ✓XT25Q08D → 0x0B 0x25 ... ✓新料号未命中 → unknown IDNo SPI NAND / unrecognized JEDEC id
图 3 · 读 JEDEC ID 与 SDK 器件表命中机制
确认是「未收录」而非「读不到」

用示波器 / 逻辑分析仪抓 CS#、SCLK、SI、SO:若能看到主控发 9Fh 且器件回了正确 ID 字节, 只是启动日志仍报 unknown ID,那就是表没收录;若总线上根本没波形或回 ff/00, 那是板级接线 / 电源 / 时序,不在本文范围(见纪律篇)。

3.2 立即动作(产线止血)

  1. 回读 ID 字节:在 u-boot 命令行用 sf probe / 平台提供的 nand 工具读 ID,记下 MID|DID|容量。
  2. 比对 SDK 器件表:在 drivers/mtd/nand/spi/ 与 u-boot-*/drivers/mtd/spi-nand/ 里搜该 ID,确认是否缺项。
  3. 临时对照烧录:若有「官方推荐烧录方式 / 金样板工程」,先用它烧一片验证能否启动,隔离是 SDK 还是烧录问题。
  4. 金样对照:同板换一颗已收录的 XTX 料号(如 XT25F08B 在表中),能启 → 锁定是「未收录」。

3.3 根治动作(长效)

  • 加器件表项:按 datasheet 把该料号的页大小、OOB、ECC 能力、坏块策略填进 spi-nand 驱动表,必要时打 XTX 原厂提供的适配补丁。
  • 核对三个位置:海思 SDK 里 BootROM 阶段、u-boot 阶段、kernel 阶段的器件表都要覆盖,缺一就会在对应阶段断链。
  • 锁定参数卡:把料号 + SDK 版本 + 补丁号写进参数卡(第 10 章),下次换料号先查表。

3.4 边界与红线

产线案例:换料号后整批 unknown ID

现象:某安防项目把 SPI NOR 方案换成 XTX SPI NAND(XT25Q08D),烧录器能建工程、能烧、能校验通过, 但整批板子上电报 unrecognized JEDEC id,一块都起不来。

定位:串口抓 LOG 确认是 unknown ID;u-boot 命令行 sf probe 回读到正确 ID 字节, 说明器件应答正常、是SDK 器件表没收录该料号(第 1 类)。同板换已收录的 XT25F08B 立即能启,锁定根因。

处理:按 datasheet 把 XT25Q08D 的页 / OOB / ECC 参数加进 drivers/mtd/nand/spi/ 器件表并打原厂补丁, BootROM / u-boot / kernel 三段都覆盖;写进参数卡后重烧,整批恢复。

3.5 读 ID 的命令时序细节

标准流程:先发 06h 写使能,再发 9Fh,随后在 SO 上连续回出若干字节 (厂商 / 器件 / 容量,部分料号支持更长的 ID 或参数页)。回读长度与顺序以 datasheet 为准。 读回值能直接区分「板级没应答」与「器件表没收录」:

  • ff ff ff:器件没应答——CS# 没拉到、电平不对、或介质配错(板级,不在本文 7 类)。
  • 00 00 00:总线被拉低 / 短路,或上拉缺失(板级)。
  • 值对但 unknown ID:器件应答完全正常,纯器件表未收录(第 1 类本相)。
先用示波器二分,再改驱动

看到回读 ff/00,先抓 CS# / SCLK / SI / SO 波形确认主控有没有发出 9Fh、器件有没有回; 波形正常却仍 unknown ID,才动手加器件表项。跳这一步直接改驱动,往往是在板级问题上白费两天。

3.6 验证修复生效

  • u-boot 命令行 sf probe 能列出正确型号,不再 unknown ID
  • 整片上电 LOG 无 unknown id / No SPI NAND
  • 同板换问题料能稳定启动(金样对照通过)
  • 器件表 3 段(BootROM / u-boot / kernel)均含该料号
  • 参数卡已登记料号 + SDK 补丁号,并双签

3.7 器件表项示意(以 SDK 源码为准)

/* drivers/mtd/nand/spi/xtx.c —— 示意,具体字段以 SDK 与 datasheet 为准 */
{ .id = {0x0b, 0x21}, .name = "XT25F08B",
  .pagesize = 2048, .oobsize = 64, .ecc_strength = 4, ... }

三处都要有:BootROM 阶段、u-boot 阶段、kernel 阶段的器件表,缺一就在对应阶段断链。 字段值(页 / OOB / ECC)必须与 XTX 该料号 datasheet 逐条一致,禁止照抄其它料号。

现场问答(第 1 类)

Q:加了器件表还是 unknown ID? 大概率是三处(BootROM / u-boot / kernel)只加了其中一段,或 ID 字节顺序填反(MID / DID 颠倒)。逐段确认都含该料号。

Q:能不能直接改 NOR 的表项凑数? 不能。SPI NAND 与 NOR 的页 / OOB / ECC 完全不同,凑 ID 会让后续第 2 类爆发。

红线:不要盲目照抄表项

往器件表里加料号时,页大小 / OOB / ECC 强度必须与 datasheet 一致。 只把 ID 加进去、参数填错(比如把 2 KB 页填成 4 KB),会导致后续第 2 类(ECC/OOB)失败, 症状从 unknown ID 变成更隐蔽的 ECC error。厂商 ID 标「常见值」的,一律以具体料号 datasheet 复核。

4. 第 2 类:ECC 与 OOB 布局不一致

现象:BootROM 能读到 ID(说明第 1 类已过),u-boot 加载镜像或 kernel 读页时大量报 ECC error、uncorrectable,甚至数据静默出错。根因是烧录器写 OOB 时按自己的 ECC 强度 / 布局落盘, 海思 NAND 控制器按另一套解释 OOB,两者对不上。

4.1 原理

SPI NAND 每页除数据区外还有 OOB 区,用于存放 ECC 校验码、坏块标记(BB)、 spare 等。 烧录器写 OOB 的字节划分(ECC 占多少、坏块标记放哪、其余留给谁)和 海思控制器读 OOB 的字节划分必须完全一致,否则控制器会把烧录器写的 ECC 字节当成数据、把数据当成 ECC, 读出即错位。

第 2 类机制:同一页的 OOB,烧录器与控制器解释成两套 → 读出错位烧录器侧 OOB 布局(2 KB 页 + 64 B OOB 示例)Page data 2048 BOOB 64 B:ECC 32BBB 2B其它 30B烧录器按此布局写 OOB(ECC 占 32 B)海思控制器侧 OOB 布局(同页同 OOB)Page data 2048 BECC 28BBB 2B保留 34B控制器按此布局解释 OOB(ECC 占 28 B)ECC 字节数 / 位置不同 → 读出 OOB 解释错位 → ECC error 或数据错
图 4 · 烧录器与海思控制器 OOB 布局不一致
典型触发动作

换了一台烧录器 / 升了烧录器算法库,或烧录工程里 ECC 强度选错(如器件支持 4 bit 却按 8 bit 烧); SDK 里的 ECC 配置(如 nand-ecc-strength、nand-ecc-step-size)与烧录器不一致。

4.2 立即动作

  1. 抓 ECC 报错 LOG:记下是「读 ECC error」还是「写 ECC error」、发生在 u-boot 还是 kernel。
  2. 核对烧录器 ECC 配置:确认烧录工程里 ECC 强度 / OOB 布局选项,与海思 SDK 的 nand-ecc-* 一致。
  3. 对齐 OOB 布局:按 XTX 料号 datasheet 的 OOB 建议,让烧录器与控制器用同一套 ECC 字节数 / 位置。
  4. 重烧验证:改完重新烧录 + 上电,看 ECC error 是否消失。

4.3 根治动作

  • 把 ECC / OOB 锁进参数卡:烧录器与 SDK 两侧的 ECC 强度、step size、OOB 布局写死,禁止产线自由改。
  • 用官方推荐烧录方式对照:若有海思官方推荐的烧录工程,以其 ECC/OOB 为基准对齐。
  • 交叉验证读回:烧录后用平台工具按逻辑地址读回关键区,确认 OOB 字节与预期一致。

4.4 边界

产线案例:升了烧录器算法库后 ECC error 暴增

现象:烧录器算法库升级后,某批次板子 u-boot 加载内核时大量 ECC error,旧算法库批次正常。

定位:LOG 显示读页即报 ECC 不可纠;查烧录工程发现新算法库把该料的 ECC 强度默认改成了 8 bit, 而海思 SDK 按 4 bit 配置(nand-ecc-strength)。第 2 类:OOB 里 ECC 字节数对不上。

处理:把烧录工程 ECC 强度改回与 SDK 一致的 4 bit,OOB 布局按 XTX datasheet 对齐; 锁进参数卡后重烧,ECC error 消失。教训:算法库升级要视同参数变更,走首件检验。

4.5 常见页 / OOB 组合(示例,以 datasheet 为准)

不同 XTX 料号的页大小、OOB 大小、ECC 能力不同,下面仅为常见取值示例,动手前必须逐料号核对 datasheet, 禁止跨料号套用。

页大小OOB 常见大小ECC 常见强度说明
2 KB64 B / 128 B4 bit / 8 bit最常见的小容量 SPI NAND(示例)
4 KB128 B / 256 B8 bit大容量 XTX 料号(示例)
(具体以 datasheet)——禁止跨料号套用,逐料号复核

4.6 验证修复生效

  • u-boot / kernel 阶段 ECC error 消失
  • 烧录工程 ECC 强度 / step = SDK 的 nand-ecc-*
  • OOB 字节位置与 XTX datasheet 一致(ECC / BB / spare)
  • 重烧后装板读回关键区无数据错位
  • 参数卡 ECC 字段已锁定,产线不可自由改

4.7 OOB 解释错位的读回差异(示意)

# 烧录器视角 OOB(ECC 32B):  [ECC·32][BB·2][spare·30]
# 控制器视角 OOB(ECC 28B):  [ECC·28][BB·2][resv·34]
# 控制器读时把烧录器的 spare 前 4 B 当 ECC 校验码 → 校验失败 / 数据错位

差异往往只有几个字节,但足以让整页 ECC 不可纠。对齐的判据是:两侧 ECC 字节数、坏块标记位、spare 划分完全一致。

现场问答(第 2 类)

Q:烧录器没有 ECC 选项怎么办? 说明该烧录器按器件默认 ECC 写,必须与 SDK 默认一致;若 SDK 改过 ECC,必须换支持自定义 ECC 的烧录方式。

Q:ECC error 只在高温出现? 多指向时序 / 电平临界而非 ECC 配置,先查板级电源再查 ECC。

ECC 强度以 datasheet 为准

XTX 不同料号 ECC 能力不同(如 4 bit / 8 bit),强度标「常见值」的须以具体料号 datasheet 复核。 把不支持的 ECC 强度强加给器件,会立刻出现 uncorrectable;反之过弱则失去纠错意义。 OOB 里坏块标记字节位置也因料号而异,必须对照 datasheet。