只读分享解决方案文档原理方案设计📅 2026-10-14🔖 Rev 1.0⏳ 还有3日到期
🔧解决方案&应用市场分析 -> 原理方案设计 -> 电子设计&技术探讨 -> 嵌入式启动介质与启动架构

嵌入式启动介质与启动架构

同系列 · 原理方案设计
扫码打开本页
微信扫码

嵌入式启动介质与启动架构

从 BootROM → XIP 直跑 → bootloader / loader → 操作系统这条链出发,讲清四类启动介质该怎么排 —— 一份跨 MCU 与 Cortex-A 两类平台的通用基础篇 | 编制日期 2026-10-14 | 版本号 Rev 1.0

4 类
启动介质
片内 BootROM · SPI NOR · SPI/SD NAND · eMMC/UFS
4 段
启动链阶段划分
ROM 初始化 → 介质初始化 → 加载 → 移交
4 维
选型排序依据
启动确定性 · 失效率 · 成本 · 可维护性
16 图
内联示意图
流程 · 时序 · 对比矩阵 · 决策树

报告总结

嵌入式项目里,「启动介质选哪一颗」这个问题几乎总是被简化成一道容量题:代码装不下就换大一档的器件。但真正决定方案的从来不是容量,而是四件更靠前的事——启动时刻的行为是否确定、介质本身会不会失效率、成本落在哪一段、出了问题能不能维护。

这份文档要做三件事:

  • 把启动链拆成可对齐口径的四段:复位与取指、ROM 初始化、介质初始化、加载与移交。每一段谁做、做什么、占多少时间,都给可套用的模板。
  • 把四类介质放进同一套语言里对齐:片内 BootROM、SPI NOR、SPI NAND / SD NAND、eMMC / UFS,分别讲清它们「启动友好」在哪里、代价在哪里。
  • 给一个能落到具体场景的排序框架:不用容量排序,用启动确定性、失效率、成本、可维护性四维排序,并给出五类典型产品的推荐级别总表与自查清单。

覆盖 MCU 与 Cortex-A 两类平台:前者关心代码容量与极简确定性,后者关心容量、分区与 OTA 原子性。两者共用同一套分层模型,只是每一层的权重不同。

结论: 启动介质不是按容量选的,是按启动确定性 + 失效率 + 成本 + 可维护性四个维度排的。 容量只决定「装不装得下」,而这四个维度决定「这设备能不能上线」—— SPI NOR 在小容量高确定性场景仍是首选,NAND 类介质必须配套一块 NOR 才敢用来做引导,eMMC / UFS 是大容量与 OTA 原子性的必选项而非可选项。 先把「谁做第一段引导代码」这件事定下来,再谈容量与价格。

读者路径

  • 要做选型决策:直接看第 8 章(四个维度 + 场景排序 + 自查 8 问)与附录 B(四介质对照总表)。
  • 要理解启动链本身:按 1 → 2 → 3 章顺序读,这是从复位到操作系统接管的完整因果链。
  • 做 Cortex-A / Linux 平台:第 4、6、7 章 + 第 9 章(bootloader 与 loader 切分、安全启动信任链)。
  • 做 MCU / 裸机或 RTOS 平台:第 2、3、5 章 + 第 10 章(启动加速),重点看 XIP 与省时手段。
  • 现场排启动故障:第 11 章(三段定位法 + 12 条以上失败清单 + 案例复盘),可当手册翻。
  • 要落地时间预算与验证用例:附录 C 两个模板直接套用。

1. 启动链的四个阶段

启动不是一件事,而是一条被切成四段的链。把这四段的口径统一之后,后面所有介质之间的比较才有意义——否则「启动只要 80 ms」和「启动要 2 s」很可能说的是完全不同的两段。

启动链四阶段:责任方、产出物与时间占比(占比为示意)① ROM 初始化固化代码执行最小集建立时钟与内存串口可用即停产出:最小运行环境② 介质初始化建立与介质的通路识别器件与容量准备随机读通道产出:可随机读取③ 加载解析镜像头定位并搬运镜像逐段校验完整性产出:可运行的下一级④ 移交选择镜像与版本判定是否回退跳转到操作系统产出:系统接管累计耗时占比示意:介质初始化与镜像加载通常占大头① ROM 初始化② 介质初始化③ 镜像加载与校验④ 移交四段的责任方不同:前两段多半固化在不可改的地方,后两段通常可更新。优化投在第三段最容易见效。占比为示意,不代表任何具体平台的实测结果;实际分配必须按实测回填,时间口径见 1.4 节。
图 1 · 启动链四阶段总流程:责任方、产出物与时间占比

上图是全文的骨架,后面每一章都在细化其中某一段或某一类介质:第 2、3 章讲第一段与第二段的做法(BootROM 与 XIP / 拷贝),第 4~7 章按四类介质分别展开,第 8 章把它们放进同一套排序框架,第 9~11 章处理移交、加速与排障。

1.1 从复位到第一行指令:复位向量与初始栈指针

设备上电或复位释放之后,处理器做的第一件事不是「运行你的代码」,而是从固定位置取一条指令。这个固定位置就是复位向量,通常指向一段极短的入口代码。紧跟着它的还有一件事:装载初始栈指针,让后续的函数调用有地方可退。

这两步是整条链上唯一「不可协商」的部分,它们决定了三件事:

  • 入口位置的确定性。介质上的内容可以被换、被改、被擦坏,但复位向量的位置不能变——所以启动镜像必须放在一个固定偏移处,而不是「随便找个空位」。
  • 栈的有效性。栈指针必须落在真实可写的 RAM 里。BootROM 自带的 RAM 通常很小,很多深层调用链必须靠自己尽早把栈搬走。
  • 失败的可观测性。如果连这一步都过不去,后面所有日志手段都是空的——这也是「无输出」这类故障最难定位的原因。
从复位释放到移交控制权:五个关键动作与代码所在的介质复位释放晶振与电源稳定取首条指令从向量表取指装载初始栈栈指针指向有效区ROM 初始化时钟、内存、串口移交控制权跳到外部引导代码代码在什么地方① 固化在 BootROM 里② 固化在外部介质里③ 运行时内存里五个动作里只有前两个不可协商:向量位置固定、栈必须有效。后三个都可以靠改代码调整顺序。所有时间数字均为典型量级,用于建立量级概念;实际设计必须以正式 datasheet 与实测为准。
图 2 · 复位到移交控制权的五个关键动作,以及代码各自所在的介质
动作由谁完成关键前提失败时的现象
复位向量取指处理器硬件 + BootROM 入口向量表放在固定偏移且内容有效完全无输出,连串口都没有
初始栈指针装载BootROM 入口代码栈指针指向真实可写 RAM进入入口后立刻跑飞,行为随机
最小外设初始化BootROM时钟源稳定,供电已稳住串口有乱码或时序完全不对
介质建立读通路BootROM 或外部引导代码接口引脚复用正确、时序参数合理识别不到介质,或读到全 FF / 全 00
载入并移交外部引导代码镜像头可解析、校验通过反复回到入口,或停在某一级

1.2 阶段划分:ROM 初始化 → 介质初始化 → 加载 → 移交

把启动链切成四段的理由不是「好看」,而是这四段的责任方不同、可改动程度不同、时间量级不同。分清责任方,才能在出问题时知道该找谁;分清可改动程度,才能判断哪些环节值得投入优化。

阶段典型责任方做什么产物可改动程度
第一段 · ROM 初始化片内 BootROM(固化)取向量与栈指针、最小时钟与内存初始化、串口可用一个可跳出的最小运行环境几乎不可改,只能换料号
第二段 · 介质初始化BootROM 或一级引导代码建立与启动介质的通路、识别器件、准备读出通道可按地址随机读取介质内容取决于这段代码固化在哪一级
第三段 · 加载一级 / 二级引导代码解析镜像头、定位镜像、搬运或直接执行、逐段校验可运行的下一级镜像可改,通过重烧或 OTA 更新
第四段 · 移交最后一级引导代码选镜像、判版本、做回退、把控制权交给操作系统或应用操作系统 / 应用接管可改,且常有 A/B 或多镜像机制

四段之间有两条经常被忽略的隐性契约:一是交接格式——上一段交给下一段的是什么(一段内存镜像,还是「一个可跳的地址」),这段约定决定了后面能不能灵活替换实现;二是失败语义——下一段失败时,上一段是重试、跳过、还是回退。没有这两条,启动链一旦在中间出错就只能从头重来,现场定位成本极高。

1.3 各阶段的时间预算拆解

做启动优化之前,先把时间拆到段。下面的预算表是通用骨架,具体数值必须实测填入——本文给出的是「哪一段大概占多少」的量级判断,用来决定优化投在哪一段最划算。

阶段典型量级主要耗时来源优化手段优化天花板
ROM 初始化百微秒 ~ 数毫秒量级时钟稳定等待、串口初始化提前启动时钟、去掉无关外设初始化低:固化代码基本改不动
介质初始化毫秒 ~ 数十毫秒量级接口时序、器件识别、状态复位跳过完整识别、只做最小读通路中:取决于这段代码在哪一级
加载数十毫秒 ~ 数百毫秒量级搬运数据量、校验计算、等待就绪XIP 直跑、并行校验、按需加载高:这是最大的一块可动空间
移交毫秒量级镜像选择、版本判定、跳板减少镜像个数、简化判定逻辑低:本身占比很小
预算表怎么用才有效

把预算表当成立项工具而不是验收工具:立项时按上表的量级分配各段预算并写成验收指标,量产后用实测值回填。若某一段实测远超预算,优先检查是不是把「调试打印」和「多余的外设初始化」算进了正式固件——启动时间超标最常见的原因不是代码慢,而是不该在这段做的代码被做了。

1.4 启动时间的定义边界与测量口径

「启动时间」至少有四种不同的口径,不同口径之间可以差一个数量级。对外沟通前必须先声明用的是哪一种,否则很容易被拿去做错误的对比。

口径起点终点典型量级适用场景
口径 A · 到首条有效指令复位释放第一条有效指令执行百微秒 ~ 毫秒量级MCU 实时性分析、向量表正确性验证
口径 B · 到引导代码入口复位释放一级引导代码开始运行毫秒 ~ 数十毫秒量级评估 ROM 与介质初始化是否达标
口径 C · 到系统可用上电或唤醒操作系统或应用可以响应外部输入数百毫秒 ~ 数秒量级产品规格书里写的「启动时间」多半指这个
口径 D · 到首帧画面 / 首包数据上电或唤醒界面可见 / 首个业务数据发出秒级量级带屏与带网口的整机体验指标
必须写清的条件两种取值对结果的影响
冷启动还是休眠唤醒冷启动 / 热启动休眠唤醒通常可跳过大部分初始化,可能快一个数量级
是否含调试器接入含 / 不含单步与断点会把时间拉长到数倍,且掩盖真实瓶颈
是否含外设初始化含 / 不含串口、显示、网络若放在启动链里,会主导整段时间
是否含校验与解密含 / 不含完整性与安全启动校验是启动链里最重的计算段之一
统计方式平均值 / 最大值 / 分布启动链的耗时分布往往长尾明显,只报均值会掩盖问题
样本量与温度条件常温 / 高低温 / 多批次低温与高温下的介质读时延差别可能很大

最后一行值得单独强调:启动时间的最大值往往比平均值更值得关注。用户能接受「偶尔慢一点」,不能接受「偶尔开不了机」。因此验收指标建议同时给出平均、P99 与最大三个数,并把「连续冷启动若干次全部成功」写成明确的通过准则。

1.5 一张完整启动链流程图

把前面四段合起来看,加上「失败怎么回来」这条横线,就是一张完整的启动链。图中时间占比是示意,用来说明「加载段通常是最大的一块可动空间」;每段的详细做法分别在第 2、3、5~7 章展开,移交与安全在第 9 章,排障在第 11 章。

四段之间的衔接还有一条容易忽略的主线:每一段交给下一段时,都必须已经成立一组前提,也必须事先定义好失败时的动作。复位交给 ROM 初始化时,供电与时钟源必须已稳定,失败则等待或复位;ROM 交给介质初始化时,串口必须可用,失败则打印诊断后停住;介质初始化交给加载时,镜像头必须可解析,失败则重读或转诊断模式;加载交给移交时,校验必须通过,失败则重试若干次后回退;移交交给操作系统时,版本判定必须完成,失败则回退或进恢复模式。没有这条主线,启动链一旦在中间出错就只能从头重来,现场定位成本极高。

2. BootROM:固化在硅片里的那一段代码

BootROM 是整条启动链里唯一「改不了」的一段。它的容量以 KB 计,代码量以最小可用为设计目标,能力以「刚好够用」为准。理解它的边界,就理解了后面三类介质存在的理由。

2.1 BootROM 的职责边界与它必须做的最小集合

BootROM 的设计目标只有一句:用最小的代码,把系统带到「可以读外部介质」的状态,然后把控制权交出去。为了做到这一点,它必须做且只做这几件事:

  • 建立最小运行环境:栈、少量 RAM、必要的时钟。ROM 自带的 RAM 通常很小,深调用链要靠自己尽快搬走。
  • 留一条能说话的通路:串口或调试口。这是现场唯一能拿到「卡在哪一步」的手段,没有它的 BootROM 在量产后等于黑盒。
  • 让启动介质可读:把引脚复用改对、时序参数设对、器件识别出来。这一步的难度决定了 BootROM 能不能支持大容量介质。
  • 移交:把一段「位置已知的可执行内容」交给下一段,并且约定好失败时怎么办。
BootROM 的职责边界:之内是必须做的最小集合,之外交给后续阶段BootROM 之内 · 必须做BootROM 之外 · 不该做使能并稳定最基本时钟完整的外设驱动与中断配置建立栈与最小内存可用性完整签名校验体系与密钥轮换留一条可观测的调试通路多镜像选择与回退策略让启动介质进入可读状态文件系统挂载与长期维护载入并移交第一段引导代码业务逻辑与运行时环境局限一 · 不可变更改一次要重做掩膜,周期与成本都高对策:把功能下移到可更新的一级局限二 · 容量小只放得下最小引导,功能必须外移对策:把功能下移到可更新的一级局限三 · 认证弱难承载复杂签名校验与密钥管理对策:把功能下移到可更新的一级边界划在哪,直接决定系统的可维护性:把逻辑放进 ROM 就等于放弃后续所有升级机会。BootROM 的容量、支持的介质型号与接口,以所选芯片的官方资料为准。
图 3 · BootROM 的职责边界与三大局限
职责为什么必须在 ROM 里放不下的后果典型取舍
取复位向量与装载栈位置固定、必须最先执行无法启动,现象为完全无输出无取舍,必须做
最小时钟与内存初始化后续一切代码的前提读时序错乱,表现为偶发失败只做最小集合,完整初始化下移
调试口初始化唯一能在早期拿到日志的手段量产后无法定位,返修成本极高宁可少做一个外设也要留调试口
启动介质识别与读通路决定能不能从介质取代码识别失败或读到错误数据大介质往往只能做「部分识别」
完整镜像校验需要在拿到足够代码之后才能做引导代码被误改或损坏时无法发现ROM 内只做轻量校验,重校验下移
签名验证与密钥管理需要非易失的信任根无法建立安全启动信任链通常只放公钥或公钥哈希
多镜像选择与回退需要稳定的存储来记录尝试次数升级失败后设备变砖几乎必须放在可更新的一级
为什么「留一条调试通路」优先级这么高

BootROM 里多放几千字节去初始化一个用不上的外设很容易,但省下这几 KB 去留一个调试口,是整个产品周期里回报最高的决定。BootROM 里的串口输出不依赖操作系统、不依赖外部介质、不依赖任何镜像是否有效——它是唯一能在「什么都还没起来」的时候说话的手段。缺了它,第 11 章里一半的排查建议都会退化成「换一颗料试试」。

2.2 掩膜固化 vs 预烧录 Flash 内的引导代码:取舍

「引导代码放在哪里」实际上有两条路:固化进硅片(掩膜)或预烧进外部 Flash 的固定偏移。两者不互斥,实际产品常常是「ROM 一小段 + Flash 一段」的两级结构。选择哪条,看四个维度:

维度固化在 BootROM(掩膜)预烧进外部 Flash 固定偏移怎么取舍
可改动性不可改,改动要重做掩膜可随时重烧,分钟级有 BUG 修复需求就必须放在 Flash
启动确定性最高,不受器件与外部接口影响依赖接口正确、器件正常、供电正常功能安全与高可靠场景偏向 ROM
能力上限以 KB 计,只能做最小引导可做完整识别、完整校验甚至二级引导需要复杂介质初始化就必须放在 Flash
供应链随晶圆固化,交期长产线后段烧录,可并行量产爬坡期 Flash 方案更灵活
防篡改天然不可改,可作为信任根可被改写,需额外的签名或写保护机制安全启动的信任根只能是 ROM
两级结构是目前最常见也最实用的折中

典型做法是:ROM 只负责「把 Flash 里的第一段读出来」这件事本身(可能只有几百字节到几 KB),第一段引导代码放在外部 Flash 的固定偏移上。这样既拿到了 ROM 的确定性,又拿到了 Flash 的可维护性。代价是多了一次交接,交接协议的严谨程度直接决定系统的健壮性——这正是 2.5 节要讲的内容。

2.3 BootROM 的局限:不可变更、容量小、认证能力弱

上一节的表格已经列出了具体表现,这里把三条局限的根因与后果讲透,因为它们直接决定了第 4 章的选型结论。

这三个局限互相强化,最终形成一个很难挣脱的局面:不可变更让现场发现的 BUG 只能等下一颗料、产线不良品无法现场救活;容量小让它无法容纳完整介质初始化、完整校验与复杂人机交互,只能把识别与校验拆到一级去做;认证能力弱则因为存放密钥需要非易失且不可读的存储,导致真正的签名验证难以实现——应对方式是让信任根只保存公钥或公钥哈希,对称材料外置加密存储。此外还有一条常被忽略的局限:调试受限,ROM 内无法用常规手段观测内部状态,失效分析只能靠猜,因此必须在设计时就预留诊断输出与失败标志位。

把这四条放在一起看,结论其实很直接:BootROM 是一个「兜底 + 引导」的角色,不是一个「运行」的角色。任何需要版本迭代、需要复杂协议、需要承载业务逻辑的功能,都不应该放在 ROM 里。这条判断准则比任何具体容量数字都可靠。

2.4 BootROM 常见失败模式与现场排查

BootROM 层面的失败有个共同特点:因为这段代码不可改,所以现场遇到时几乎没有软件手段可以救。因此这一层的工作重心是预防而不是修复。下面按现象归类,给出首查项。

现象最可能的原因首查项可否软件补救
完全无串口输出时钟未起或串口引脚复用不对供电时序、时钟源、引脚复用配置基本不能,需改料
反复输出同一段信息后复位找不到合法镜像头,反复回到入口镜像偏移、头部长度、校验字段可以,重新烧镜像
能读到器件标识但读数据全 FF / 全 00读命令时序或地址宽度不匹配地址字节数、页内偏移、读时序参数可以,重新配置
大容量器件能识别、小容量不行ROM 内做了器件选择分支,漏了目标型号器件支持列表是否包含目标料号看是否被裁剪过
低温才偶发失败时钟建立时间不够或时序余量偏紧建立时间、时序参数余量、上电斜率较难,需重新规划时序
串口有输出但内容乱码波特率或时钟源配置不一致时钟源切换点、波特率计算可以,改外部配置
同一批板子有个别完全无输出焊接或供电个体差异供电轨电压、焊接、上电时序基本不能,属生产问题

2.5 BootROM 与外部 Flash 引导代码的衔接协议思路

两级结构的核心是那个「交接」。交接协议不需要多复杂,但必须把三件事定义清楚:交的是什么、失败了怎么办、怎么知道上一段做完了。

  1. 交的是一段确定位置的镜像:约定镜像头在介质的固定偏移,头里至少有长度、目标加载地址、校验信息。ROM 只负责把头部与正文读到并校验,不解析任何复杂格式。
  2. 失败语义要先定好:头部无效或校验不通过时,是重试、跳到备用位置、还是进入一个最小诊断模式。这一条决定了现场是「起不来但能说话」还是「彻底黑盒」。
  3. 要有可观测的交接记录:至少保留「当前停在哪一级、失败原因是哪一类」的状态。这些状态既用于现场的串口输出,也用于第 11 章讲的故障快照。
协议要素作用不定义会怎样建议做法
镜像头固定偏移与对齐让 ROM 不需要目录就能找到入口ROM 要么找不到、要么误把数据当代码固定对齐偏移,偏移值本身也参与校验
头部长度与字段含义让 ROM 能跳过不认识的新字段固件版本一升就变砖头部预留扩展区,未知字段按约定跳过
目标加载地址支持搬运到任意 RAM 位置只能原地执行,RAM 布局被锁死在头部显式声明,加载地址需做合法性检查
失败重试次数与去向避免无限循环现场看到设备反复重启设有限重试次数,之后进入诊断模式
运行标志与回退计数支持升级失败后回退升级失败即变砖用介质的固定扇区存放,成功后再清除
诊断输出约定让现场能判断停在哪一级只能靠拆机换料固定格式打印阶段号与失败类别
判断衔接协议是否合格的一条标准

把镜像头里 ROM 不认识的字段全部填成随机数据,系统仍然能正常启动到应用,就说明协议有扩展余量;再把头部校验改坏,系统应当停在一个能说话的地方而不是死循环或彻底无输出。这两个测试做下来,衔接协议的健壮性基本就心里有底了。

3. XIP 直跑与拷贝运行的分野

这是启动链上一个真正的分叉点。同样是「从 Flash 里取代码执行」,可以完全不碰 RAM,也可以先老老实实搬一遍。两者的代价结构完全不同,适用条件也完全不同。

3.1 XIP 的原理与前提:可随机访问的接口

XIP(Execute In Place,原地执行)的做法只有一句话:把一段外部存储映射到处理器地址空间里的一个固定窗口,取指时硬件自动去读那块存储。程序计数器指向这个窗口内的地址,CPU 以为自己在读内存,实际上每次取指都变成了一次外部读。

它成立的前提有三条,缺一条就不成立:

  • 接口必须支持随机访问。给一个地址就要能在合理时间内返回对应的数据,而不能要求「必须从头顺序读」。这是 NOR 天然具备、NAND 天然不具备的差别。
  • 读时延必须足够确定。取指对时延抖动比数据访问更敏感——一次不确定的等待会让 CPU 的流水线频繁停顿,表现为「代码跑得慢但说不清为什么」。
  • 不需要修改内容。XIP 期间介质里的内容是当作指令读的,不能是压缩包、加密包或需要运行时重定位的格式。这条常被忽略:如果镜像需要解压或解密,就不可能纯 XIP。
同样一段代码,两种执行方式:XIP 直跑与拷贝到 RAM 运行XIP 直跑:地址窗口直接映射CPU 取指 → 介质读 → 拿到指令 → 执行CPU 取指外部读拿到指令并执行① 介质可随机访问:给地址就能读② 读时延要够确定,否则取指抖动③ 读介质里的数据不占 RAM 缓冲④ 代价:每次取指都占外部总线拷贝运行:先搬进 RAM 再跳过去CPU 顺序读 → 搬进 RAM → 跳到 RAM 执行顺序读介质RAM 缓冲区从 RAM 执行① 介质只要能顺序读,不强制随机② 搬运期间可做并行预取③ 需要与代码等大的 RAM 缓冲④ 代价:搬运本身要花时间一句话判断:代码不大、要求确定 → XIP;代码偏大、介质不擅随机读 → 拷贝两条路径都要校验:XIP 通常在跳转前做一次头部校验,拷贝则可在搬运过程中边搬边校验。耗时为典型量级,实际以正式 datasheet 与实测为准;总线带宽、等待状态与介质时序都会影响结果。
图 4 · XIP 直跑与拷贝到 RAM 运行的流程与代价对比
维度XIP 直跑拷贝到 RAM 运行
对介质的要求可随机访问、读时延确定、可映射到地址空间顺序读即可,允许较长的块读时间
RAM 需求仅需栈与少量数据,几乎不需要大块代码缓冲需要与待运行镜像等大或更大的 RAM
启动耗时构成无搬运时间,但执行期持续付出读时延一次性搬运时间,之后执行很快
镜像可压缩 / 可加密不可以可以,搬运前先解密解压
执行期总线占用高:每次取指都要走外部总线低:执行期只访问 RAM
实时性受介质读时延抖动影响执行期确定性好,但启动点有一段集中延迟
典型平台带 NOR 且支持映射窗口的 MCU几乎所有平台都可用的兜底方案

3.2 拷贝运行的流程与代价

拷贝运行是最普适的方式:任何能读出字节的介质都能用,代价是多花一段搬运时间和一块 RAM。

典型流程是四步:

  1. 确定源地址与长度:从镜像头读出加载地址与长度,并检查目标区域是否可用。
  2. 搬运:按块或按页把内容读进 RAM 缓冲区。这一步可以边读边校验,把校验开销和搬运重叠掉。
  3. 校验:整段搬完后确认校验通过,再决定是否跳转。中途失败应回到重试计数,而不是带着半个镜像往下走。
  4. 重定位与跳转:若代码含绝对地址,需要做重定位;然后跳到 RAM 里的入口。

拷贝的真实代价有三笔:搬运占用的启动时间、被占用的 RAM、以及RAM 布局被镜像大小绑架。第三笔最容易被忽略——一旦代码膨胀到 RAM 放不下,就得回头改架构,这在大内存 Linux 平台上尤其常见(此时解法是把内核分段加载,而不是整块进 RAM)。

成本项量级由什么决定能不能省
搬运时间与镜像大小和总线宽度成正比总线宽度、等待状态、介质连续读能力能:用 XIP、或只搬下一级需要的部分
RAM 占用与镜像大小成正比RAM 总量与系统其他用途的分配能:分级加载、或用 XIP
重定位时间通常很小镜像内绝对地址引用的数量部分能:编译时生成位置无关代码

3.3 XIP 对介质的要求:读延迟确定、无需 ECC 重算、可映射到地址空间

把上面的前提展开成下面四条可核查的判据。这四条里任意一条不满足,XIP 就会从「省时间」变成「浪费时间」甚至「跑不起来」。

要求具体含义怎么核查不满足的后果
读延迟确定连续读与随机读的耗时差异可控,且有明确上界看时序参数与实测分布,不只看典型值取指停顿,实时性不可控
无需 ECC 重算读取时不需要软件参与纠错,或纠错开销可忽略区分「有硬件 ECC」与「需软算」两种介质每次取指都要算错误,启动慢到不可接受
可映射到地址空间能把介质地址空间的一个窗口挂到总线地址上看器件是否支持该模式、窗口大小与粒度限制只能退回拷贝运行
内容可直接执行介质里的字节就是可执行指令,不需先变换确认镜像是否压缩、加密、含重定位信息需先搬运到 RAM 再跳转
为什么 NAND 类介质基本不做 XIP

NAND 的读出粒度是「页」,而且读出之前需要控制器做坏块映射与纠错——这两件事不是纯硬件地址映射能完成的,它需要一段软件参与。因此把 NAND 映射到地址空间直接执行,在多数实现里并不成立;即使硬件上能映射,纠错带来的延迟与不确定性也让 XIP 失去意义。这正是第 6 章要展开的核心障碍。

3.4 混合模式:XIP 启动 + 拷贝到 RAM 运行

实际产品里最常见的不是二选一,而是混合:用 XIP 把「小而关键」的第一段代码跑起来,再由它把「大而不急」的部分拷到 RAM 执行。典型分工是:

  • XIP 区:复位向量、中断向量表、时钟与内存初始化、介质初始化、镜像头解析。这些加起来通常只有几 KB,但必须在最快路径上跑完。
  • 拷贝区:主应用、图形资源、需要解密的模块、模型权重。这些大块内容在启动后慢慢搬,搬完再启用。

这个混合模式的四个区段可以这样划分:XIP 区放向量表、时钟与内存初始化、介质初始化——体量小、在关键路径上,必须最快完成;校验区做镜像头与首段校验,用直接执行加少量栈空间即可,因为跳转前必须确认正确而成本很低;拷贝区放主应用与大数据段,体量大、执行期需要高速与确定,必须搬进 RAM;延后区放日志、网络、外设驱动,它们不属于「可用」的必要条件,可以放到启动完成之后再初始化。

混合模式的关键设计点是「在哪里切换」。切换点之前不能依赖任何未初始化的东西,包括 RAM 里未清零的区域、外部设备、甚至栈上的返回值。一个实用的做法是把切换点做成一次显式的、带日志与失败回退的跳转,让它成为一个可观测的事件——这也是第 11 章做故障快照时最有价值的一个时间锚点。

3.5 五种启动方式的对比矩阵

把常见的五种方式放进同一张表,就能看清各自的适用边界。矩阵的价值不在于「哪个最好」,而在于每种方式放弃了什么。

五种常见启动方式对比:谁做第一段、对介质和 RAM 各有什么要求启动方式谁做第一段介质初始化量RAM 需求启动确定性① 纯 BootROM 直跑ROM不需几乎不需最高② BootROM 拷贝到 RAMROM不需需较大高③ SPI NOR XIP 直跑ROM + NOR不需不需高④ SPI NOR 拷贝到 RAMROM + NOR不需需较大高⑤ 容量介质分级加载三级分工需完整识别需中量中读法:横向看这一方式要付出什么代价(介质初始化量、RAM 占用),纵向看它落在平台的哪一档能力上。五种方式不是互斥的:实际产品常是「① + ③」或「① + ④」的两级组合,用 ROM 保证确定性、用外部介质保证可维护。
图 5 · 五种启动方式对比矩阵:责任方、介质初始化量、RAM 需求与确定性
启动方式对介质的要求对 RAM 的要求启动确定性可维护性典型适用
① 纯 BootROM 直跑无外部介质几乎不需要最高最低极小代码 MCU,一级镜像固定不变
② BootROM 拷贝到 RAM顺序读即可需较大高低代码略大但仍需不可变启动
③ SPI NOR XIP 直跑NOR 支持映射窗口几乎不需要高中外部 NOR 足够大、要求启动快的 MCU
④ SPI NOR 拷贝到 RAM顺序读即可需较大高中NOR 不支持 XIP 时的主流选择
⑤ 容量介质分级加载需完整识别与分区解析需中量中最高Cortex-A 平台、大容量、需 OTA 原子性
选型时先问一句:这段代码需不需要被更新

如果不需要更新(生命周期极短、成本敏感、产量巨大),纯 BootROM 或 BootROM + 小容量固定镜像最省事;如果需要更新,就必须把可变的部分放到可写的外部介质上,此时「ROM 只做引导、外部介质做全部逻辑」的分层几乎总是对的。这个问题比「要不要 XIP」重要一个数量级。

4. 第一类介质:片内 BootROM 与 eMCP 类内置

第一类介质的共同点是:启动代码和介质都在芯片内部,外部总线上没有任何启动器件。这一类方案启动确定性最好、成本最省,代价是容量极小、几乎不可变更。

4.1 纯 BootROM 方案的启动时序与代码容量约束

纯 BootROM 方案的启动链只有三步:取向量、建最小环境、跳转到固定地址。它的时间短到几乎可以忽略,真正的约束是代码容量。

ROM 容量以 KB 计,且面积直接对应成本。经验上 ROM 里放不下复杂的东西:完整的介质识别、完整的镜像校验、复杂的中断管理、任何需要较大表格的逻辑——这些都会迅速把体积推上去。所以纯 BootROM 方案里的主程序通常是「极小的固定代码 + 尽可能少的逻辑」,真正的功能在别处(可能是不可编程的应用专用逻辑,也可能是固化在另一片 ROM 里)。

时间上,取向量与装载栈在百微秒以内量级,最小环境初始化在百微秒到毫秒量级,校验固定镜像在毫秒量级,跳转本身是微秒量级。真正需要分配预算的不是这些动作,而是「校验」这一段——它随镜像大小与算法复杂度线性增长,是纯 BootROM 方案里唯一可能变慢的地方。

4.2 eMCP / uMCP 这类把控制器与 Flash 合封的价值:省掉外部介质初始化

eMCP、uMCP 这类器件把存储控制器与 Flash 阵列合封装在同一颗芯片里,对主板而言它看起来就像一颗「带控制器的存储器」——不需要外挂控制器,也不需要复杂的裸介质时序驱动。

它对启动链的价值体现在一个具体的地方:第二阶段「介质初始化」被显著压缩。控制器已经在片内完成上电自检与初始化,主机侧只需要按标准协议发命令,不必自己写一套介质驱动。

把合封器件与外挂方案逐项对比:控制器位置上外挂方案需要主机自己驱动,合封器件片内自带;主机侧代码量上外挂 NOR 最小、外挂 NAND 最大、合封器件居中;上电初始化上外挂 NOR 简单,外挂 NAND 需要强制状态读与参数下发,合封器件由控制器内部完成;启动确定性上外挂 NOR 最好、外挂 NAND 最差;现场可修复性上外挂方案可以换芯片,合封器件焊死在板上,通常要整板返修;适用容量段上外挂 NOR 面向小容量、外挂 NAND 面向小到中容量、合封器件面向中容量。

合封最大的代价是「不可现场修复」

把控制器与 Flash 合封,换来的是启动简化和更好的性能,但同时失去了「通过更换外部芯片来救回一台设备」的能力。当固件有缺陷、需要靠更新覆盖修复时,合封器件内部的 Flash 内容就成了一次性资源。因此选择合封方案前,必须确认两件事:一是内部 Flash 内容有可行的升级路径;二是即使升级失败,也不会让设备永久报废。这两条不成立时,合封带来的好处抵不过它的风险。

4.3 内置控制器带来的启动简化与代价

把「内置控制器」这件事的收益与代价摊开看,收益集中在启动链的第二阶段,代价则集中在灵活性与可修复性两个维度。

方面收益代价如何权衡
启动代码量主机侧不必实现介质时序与纠错,代码显著变短仍需实现命令交互层,代码量不为零优先保证代码量能放进 ROM
启动时间省掉器件识别与状态恢复,缩短第二阶段控制器内部初始化有固定开销,不可跳过按实测分配预算,不要假设可省略
介质灵活性接口统一,换料号时主机代码改动小被限制在合封器件支持的容量与形态内容量规划留足余量,避免顶格设计
可维护性无不可现场更换器件,返修要动板必须有可用的升级路径兜底

4.4 适用边界:不可现场升级 Flash 内容本身时怎么办

这是第一类介质最常被问到的问题。答案取决于「不可升级」的到底是哪一部分——这一点必须先分清,否则方案会做错。

不可升级的范围典型形态应对策略残余风险
只有 BootROM 不可升级掩膜 ROM + 外部可写介质把全部可变逻辑放外部介质,ROM 只做引导ROM 自身有 BUG 时只能换料
内部 Flash 可升级但需专用流程合封器件,OTA 或特殊通道写入设计成双区或外部备份引导路径升级通道本身失效时无退路
内部 Flash 完全不可升级掩膜 ROM 是唯一存储只能靠一次性正确的固化,功能必须做减法有缺陷即产品缺陷,需极严格验证
外部有可写介质但容量不足小容量 NOR + 大 ROM只把关键数据放外部,其余固化数据容量受限,需明确取舍
对「完全不可升级」方案的止损建议

如果确实只能用不可升级的固化代码,那么验证强度必须同步提高一个等级:固化内容一旦出错,成本是整批返修甚至整机报废。可行的做法包括:固化前对镜像做完整性与功能双重验证、在产线上保留可观测的启动诊断输出以便快速判定问题归属、以及在设计评审时就把「哪些功能绝对不能放进固化代码」写成明确的红线。

相关报告 · 交叉引用 6 器件全部展开收起 ▾
点开类目即可展开:具体文档 / 章节(点章直接跳转到该章)
eMMC
电路设计指南
软件设计规范
Linux 驱动开发
样机问题排查
量产问题排查
SPI NOR
电路设计指南
软件设计规范
Linux 驱动开发
样机问题排查
量产问题排查2
系统设计指南
SD NAND
电路设计指南
软件设计规范
Linux 驱动开发
量产问题排查
SPI NAND
电路设计指南
软件设计规范
Linux 驱动开发
样机问题排查
量产问题排查4
全志平台 SPI NAND NOR
章节(点章跳转,共 11 章)
海思平台 SPI NAND 量产常见失败
章节(点章跳转,共 11 章)
烧录成功但不开机 SPI NAND
章节(点章跳转,共 12 章)
瑞芯微平台 SPI NAND eMMC
章节(点章跳转,共 11 章)
系统设计指南3
eMCP/uMCP
电路设计指南2
软件设计规范2
其他提及器件(共 1)
DDR/LPDDR(DRAM)
电路设计指南4
软件设计规范4
DDR2
章节(点章跳转,共 16 章)
DDR3
章节(点章跳转,共 16 章)
DDR4
章节(点章跳转,共 17 章)
DDR5
章节(点章跳转,共 17 章)