嵌入式系统基础回顾:MCU与MPU的差异与启动流程
做固件逆向分析,第一步得搞清楚你面对的是什么芯片。我见过不少新手,拿到一个固件就开始反汇编,结果连芯片是MCU还是MPU都没搞清楚——这就像修车不看发动机型号直接拆螺丝,很容易翻车。
这一章我们快速过一遍嵌入式系统的基础概念。别觉得基础就跳过,我跟你讲,逆向分析中90%的坑都出在基础概念混淆上。
MCU vs MPU:核心差异
先看一张对比表,把最关键的几个维度列出来:
| 对比维度 | MCU(微控制器) | MPU(微处理器) |
|---|---|---|
| 典型芯片 | STM32F4, ESP32, nRF52840 | i.MX6, RK3399, Allwinner H3 |
| 内部存储器 | 片内Flash + SRAM | 无片内Flash,需外挂DDR |
| 启动方式 | 直接从片内Flash执行 | 从外部存储加载到DDR |
| 操作系统 | 裸机或RTOS | Linux / Android |
| 功耗 | 毫瓦级 | 瓦级 |
| 逆向关注点 | 中断向量表、Bootloader | SPL、ATF、设备树 |
说白了,MCU是"单片机",芯片内部集成了Flash和RAM,上电就能跑。MPU是"应用处理器",它本身只是个计算核心,需要外挂DDR和存储芯片才能工作。
我的经验:有一次我拿到一个IoT设备的固件,反汇编后发现地址空间从0x80000000开始——这明显是MPU的DDR地址。但团队里有人坚持认为是MCU,结果浪费了两天时间。记住:看启动地址就能判断芯片类型。
常见嵌入式架构
目前市面上主流的架构就这几种,我按逆向分析的难度排个序:
ARM Cortex-M 系列
这是MCU的绝对主力。Cortex-M3/M4/M7/M33,你拆开90%的智能硬件都能看到它们。特点:
- 中断向量表固定在0x00000000或0x08000000
- 启动时从向量表取栈指针和复位向量
- 指令集是Thumb/Thumb-2,没有ARM模式
避坑指南:我曾经反汇编一个Cortex-M4的固件,用ARM反汇编引擎打开全是乱码。后来才想起来——Cortex-M只能用Thumb指令集,反汇编器必须指定Thumb模式。这个坑我踩过,你别再踩了。
ARM Cortex-A 系列
这是MPU的主力。Cortex-A7/A53/A72,跑Linux的嵌入式设备基本都是它。特点:
- 支持ARM和Thumb两种指令集
- 启动流程复杂:ROM code → SPL → U-Boot → Kernel
- 有MMU,地址是虚拟地址
RISC-V
开源指令集,这几年火得不行。国内很多芯片厂商都在推。逆向分析时要注意:
- 指令长度可变(16/32/64位)
- 启动地址由硬件配置决定
- 工具链还在完善中,反汇编器支持不如ARM成熟
Xtensa
乐鑫ESP32用的就是这个架构。特点:
- 可配置指令集,每个型号可能不一样
- 有窗口寄存器,函数调用时寄存器窗口会滑动
- 反汇编工具比较小众,IDA Pro需要装插件
启动模式与存储介质
启动模式决定了芯片上电后从哪里加载代码。我画了一张流程图,把常见的启动路径串起来:
存储介质详解
不同的存储介质,逆向分析时看到的固件结构完全不同:
| 存储类型 | 特点 | 逆向分析要点 |
|---|---|---|
| NOR Flash | 支持XIP(片内执行),字节寻址 | 固件可以直接反汇编,地址就是运行地址 |
| NAND Flash | 块设备,有坏块,需要ECC | 固件需要先提取,注意OOB区域可能存校验 |
| SPI Flash | 串行接口,容量小,速度慢 | 常见于MCU,固件头部有加载地址信息 |
| eMMC | 内置控制器,分区管理 | 需要解析分区表,固件可能分散在多个分区 |
注意:NAND Flash的固件提取有个大坑——坏块。我曾经从一台设备上dump NAND Flash,读出来总是校验失败。后来才发现,厂商在生产时跳过了坏块,但dump工具是按顺序读的。你必须先解析坏块表,才能得到正确的固件镜像。
启动模式(Boot Mode)
芯片上电后,第一件事就是检查BOOT引脚的电平状态。不同的电平组合决定了从哪个介质启动。常见的启动模式有:
- Flash启动:从片内Flash或外部SPI Flash启动,MCU的默认模式
- 系统存储器启动:从芯片内部ROM中的Bootloader启动,用于ISP下载
- SRAM启动:从内部SRAM启动,调试时常用
- SD卡/eMMC启动:MPU的典型启动方式
我个人的习惯是,拿到一个设备先看PCB上的BOOT引脚。如果有跳线或拨码开关,十有八九是MPU。如果啥都没有,大概率是MCU直接从Flash启动。
小结
这一章的内容就这些。记住几个关键点:MCU和MPU的启动流程完全不同,存储介质决定了固件的组织形式,启动模式决定了从哪里加载代码。这些基础概念搞清楚了,后面分析固件加载流程的时候才不会懵。