嵌入式系统基础:MCU与MPU的区别、常见嵌入式架构、外设与总线

做逆向分析,第一步得搞清楚你手里拿的到底是什么芯片。我见过不少新手,拿到一个固件就开始反汇编,结果发现指令集都猜错了——那基本等于白干。所以这一章,咱们先把嵌入式系统的几个核心概念理清楚。

MCU vs MPU:两个世界的差异

很多人把MCU和MPU混着叫,其实它们差别挺大的。说白了,MCU(微控制器)是把CPU、内存、外设全塞进一颗芯片里,适合做控制类任务。MPU(微处理器)则更像电脑的CPU,需要外接DDR、Flash才能跑起来。

对比维度 MCU(微控制器) MPU(微处理器)
集成度 片内集成Flash、SRAM、外设 需外接存储器、外设控制器
典型频率 几十MHz ~ 几百MHz 几百MHz ~ 数GHz
内存管理 无MMU,直接物理寻址 有MMU,支持虚拟内存
操作系统 裸机或RTOS(FreeRTOS、uC/OS) Linux、Android等完整OS
功耗 毫瓦级,可电池供电 瓦级,通常需要散热
典型应用 传感器节点、电机控制、IoT设备 路由器、智能摄像头、工业平板
逆向难度 固件直接读Flash,结构简单 需考虑Bootloader、文件系统、加密分区
我的经验:拿到一个固件文件,先看大小。小于1MB的,十有八九是MCU;大于4MB的,基本是MPU跑Linux。这个判断方法我在项目里用了不下百次,还没翻过车。

常见嵌入式架构:ARM、MIPS、RISC-V

你想想看,全球99%的嵌入式设备,跑的无非就是这三种架构。咱们做逆向的,得能一眼认出它们。

ARM —— 市场霸主

ARM统治了嵌入式世界。从Cortex-M0到Cortex-A78,覆盖了从传感器到服务器的全场景。我个人习惯,拿到固件先看入口地址:如果复位向量在0x00000000附近,大概率是ARM Cortex-M系列;如果在0x80000000附近,可能是Cortex-A跑Linux。

  • Cortex-M系列:无MMU,Thumb/Thumb-2指令集,中断向量表在Flash起始位置
  • Cortex-A系列:有MMU,ARM/Thumb混合指令,启动流程复杂(ATF、U-Boot、Kernel)
  • 逆向特征:函数入口常见PUSH {LR},函数结尾常见POP {PC}

MIPS —— 曾经的王者

MIPS在路由器、光猫领域曾经是绝对主力。我记得有一次逆向一个老款路由器固件,反汇编出来全是MIPS指令,当时差点被它的延迟槽搞疯——每条分支指令后面的那条指令,无论分支是否跳转,都会被执行。这个坑,我踩过。

避坑指南:MIPS的延迟槽(Delay Slot)是逆向时最容易出错的地方。我曾经因为没注意延迟槽,把一个条件跳转的逻辑完全分析反了,浪费了整整两天。记住:分支指令后面那条指令,一定会执行。

RISC-V —— 新贵崛起

RISC-V这几年势头很猛,国内很多厂商都在推。它的指令集非常规整,逆向起来反而比ARM和MIPS舒服。不过目前RISC-V的生态还在建设中,调试工具链不如ARM成熟。

架构 指令长度 寄存器数量 逆向难点 常见工具
ARM (Thumb-2) 16/32位混合 16个通用寄存器 ARM/Thumb模式切换 Ghidra, IDA Pro, objdump
MIPS 32位定长 32个通用寄存器 延迟槽、分支预测 Ghidra, IDA Pro, mips-linux-gnu-objdump
RISC-V 32位定长(RV32I) 32个通用寄存器 工具链较新,符号信息少 Ghidra (支持较好), riscv64-unknown-elf-objdump

外设与总线:固件与硬件的桥梁

做逆向分析,光看懂CPU指令还不够。你得知道固件是怎么跟硬件打交道的。外设和总线,就是固件控制硬件的通道。

常见外设接口

  • UART:调试串口,经常能从这里抓到系统启动日志。我习惯在固件里搜索"UART"或"115200",往往能找到串口初始化代码。
  • SPI:连接Flash、传感器。固件里SPI的读写函数通常有固定的模式——先拉低片选,然后发送命令字节,再读写数据。
  • I2C:连接低速外设(温度传感器、EEPROM)。地址通常是7位,固件里会看到0xA0、0xD0这样的地址常量。
  • GPIO:最基础的控制方式。逆向时看到对某个地址写0或1,基本就是GPIO操作。

总线结构

现代嵌入式SoC内部,CPU通过总线矩阵连接各个外设。常见的总线有AHB(高速总线,接内存、DMA)和APB(低速总线,接UART、GPIO)。

逆向要点:固件里访问外设,本质就是读写特定的内存地址。比如STM32的USART1数据寄存器地址是0x40013824,你在固件里看到对这个地址的读写操作,就能确定它在操作串口。
嵌入式SoC内部总线结构 CPU Core AHB 高速总线 APB 桥接器 → APB 低速总线 Flash控制器 SRAM控制器 DMA控制器 UART SPI I2C GPIO 说明:CPU通过AHB总线访问高速设备(Flash、SRAM),通过APB桥接器访问低速外设(UART、SPI等)

实战视角:如何快速识别目标平台

拿到一个陌生的固件,我一般按这个流程来快速定位:

  1. 看文件头:用hexdump看前16字节。如果是ELF或PE头,直接知道架构;如果是裸二进制,看入口地址。
  2. 搜字符串:strings命令搜"U-Boot"、"Linux"、"FreeRTOS"等关键词,能快速判断操作系统。
  3. 查中断向量:ARM Cortex-M的向量表在0x00000000,第一个32位字是栈指针,第二个是复位向量。这个特征非常明显。
  4. 看外设地址:在固件里搜索常见外设基地址(比如0x40000000附近的地址),能判断芯片厂商。
小技巧:我习惯在Ghidra里加载固件后,先看"Data Type Manager"里的处理器寄存器定义。如果自动匹配到了STM32的寄存器,那基本就是ARM Cortex-M了。这个功能帮我省了不少事。

嗯,这一章的内容就这些。MCU和MPU的区别、三种主流架构的特征、外设总线的结构——这些是后面做逆向分析的基础。你把这些概念吃透了,后面分析固件的时候,心里就有底了。