1. ARM架构概述:从手机到服务器,一个架构的进化史

做嵌入式的人,没人能绕过ARM。我最早接触ARM还是十多年前做一款工业控制器,当时选型就是ARM7TDMI。说实话,那时候ARM还是个"低功耗但性能一般"的选手。谁能想到今天它从手机杀到了服务器,连苹果的Mac都换成了ARM架构。

这一节,咱们把ARM的底牌翻一翻。从发展史到产品线,再到v7和v8的核心差异。这些内容看着像背景知识,但后面讲MMU和内存模型时,你会不断回来翻这一节。

1.1 ARM发展史:一家不造芯片的芯片公司

ARM的故事挺有意思。1985年,Acorn电脑公司想做一款RISC处理器,结果搞出了ARM1。那时候没人觉得这东西能成。后来Acorn不行了,ARM独立出来,1991年正式成立ARM公司。

ARM最聪明的一步棋是什么?它不造芯片,只卖IP授权。你想想看,这意味着什么?任何公司都可以买ARM的授权,然后自己加外设、改频率、定制指令。这就解释了为什么市面上有上千种不同的ARM芯片。

关键时间节点:

  • 1985年 — ARM1诞生,26位指令集,22MHz
  • 1994年 — ARM7TDMI发布,嵌入式领域的"常青树"
  • 2002年 — ARMv5架构,Jazelle技术支持Java加速
  • 2005年 — ARMv6架构,Cortex系列首次亮相
  • 2011年 — ARMv8-A发布,64位时代开启
  • 2021年 — ARMv9发布,强调安全与AI

我个人习惯把ARM历史分成三个阶段:探索期(ARM1到ARM7)、统治期(ARM9到Cortex-A9)、扩展期(Cortex-A53至今)。每个阶段都有标志性产品,后面咱们会反复提到。

1.2 Cortex-A/R/M系列:三兄弟各司其职

很多新手搞不清Cortex-A、Cortex-R、Cortex-M的区别。我当年也犯过糊涂,选型时把A系列芯片用在电池供电的设备上,功耗直接翻倍。嗯,学费交得有点贵。

说白了,这三兄弟的分工很明确:

特性 Cortex-A Cortex-R Cortex-M
全称 Application Real-time Microcontroller
典型场景 手机、平板、服务器 汽车、硬盘控制器、基站 传感器、IoT、电机控制
MMU 有 可选(MPU) 无
操作系统 Linux、Android、Windows RTOS、裸机 RTOS、裸机
中断延迟 几十到几百纳秒 几纳秒 几纳秒
功耗 高 中 极低
代表型号 Cortex-A72、A76 Cortex-R5、R52 Cortex-M4、M7

这里有个坑我要提醒你:Cortex-R系列虽然叫"实时",但它不是硬实时。我在做汽车ECU项目时,一开始选了R5,后来发现中断响应还是不够确定,最后换成了专用DSP。选型时一定要看具体的数据手册,别光看名字。

避坑指南:我曾经在一个项目中,把Cortex-M7当主控,想跑Linux。结果发现M7根本没有MMU,Linux跑不起来。最后只能上A系列,整个方案重做。选型前先确认:你要不要跑Linux?要不要虚拟地址?要不要多进程?这些问题的答案直接决定了你选A还是M。

1.3 ARMv7-A与ARMv8-A:32位到64位的跨越

ARMv7-A是32位时代的巅峰。Cortex-A15、A9都是这个架构。ARMv8-A则是64位的新起点,Cortex-A53、A72、A76都是它的子孙。

两者的差异,我列个表你一看就明白:

对比项 ARMv7-A ARMv8-A
指令集宽度 32位 32位 + 64位
通用寄存器 16个(R0-R15) 31个(X0-X30)
虚拟地址空间 4GB(32位) 最大2^48(256TB)
物理地址空间 最大1TB(LPAE) 最大2^48
MMU页表格式 二级页表 三级/四级页表
异常模型 IRQ/FIQ/SVC等7种模式 EL0-EL3四个异常等级
兼容性 仅32位 兼容32位(AArch32)

这里有个关键点:ARMv8-A不是简单地"把32位变成64位"。它把整个异常模型重写了。ARMv7-A有7种处理器模式(User、FIQ、IRQ、Supervisor等),切换起来很麻烦。ARMv8-A改成了4个异常等级(EL0到EL3),每个等级有独立的栈指针和页表。这个设计让虚拟化和安全监控器(如TrustZone)的实现变得干净很多。

我在调试一个ARMv8-A的启动代码时,就踩过异常等级的坑。当时在EL3初始化了MMU,然后切到EL1跑Linux,结果页表全失效了。后来才意识到:每个异常等级有自己的TTBR0_ELx寄存器,切换等级后必须重新配置页表。

小技巧:如果你在做ARMv8-A的底层开发,建议先搞清楚当前在哪个异常等级。用MRS X0, CurrentEL指令可以读出来。这个习惯能帮你省掉很多调试时间。

1.4 架构演进的核心逻辑:一张图看懂

下面这张图展示了ARM架构从v7到v8的核心变化。我画的时候特意把异常模型和MMU放在一起,因为这两个是内存模型的基础。

ARMv7-A → ARMv8-A 架构演进核心变化 ARMv7-A (32位) 异常模型 7种模式 MMU 二级页表 虚拟地址 4GB 物理地址 1TB (LPAE) ARMv8-A (64位) 异常等级 EL0-EL3 MMU 三级/四级页表 虚拟地址 256TB 物理地址 256TB 关键变化解读 1. 异常模型重构:7种模式 → 4个异常等级,简化了虚拟化和安全设计 2. 页表深度增加:二级 → 三级/四级,支持更大的地址空间 3. 寄存器翻倍:16个 → 31个通用寄存器,减少栈操作 4. 地址空间爆炸:4GB → 256TB,不再受32位限制 5. 向后兼容:AArch32模式可运行32位代码,迁移成本低

1.5 为什么这些对MMU和内存模型重要?

你可能会问:学ARM架构和MMU有什么关系?关系大了。

MMU的页表格式直接由架构版本决定。 ARMv7-A用二级页表,ARMv8-A用三级甚至四级页表。如果你在调试MMU时发现页表遍历不对,第一步就是确认架构版本。

异常等级决定了谁控制MMU。 在ARMv8-A中,EL3(安全监控器)可以独立配置自己的MMU,EL1(操作系统)也有自己的MMU。这种分层设计让虚拟化成为可能,但也带来了配置的复杂性。

我记得有一次调试一个ARMv8-A的KVM虚拟化问题,客户说虚拟机里的Linux访问外设时崩溃。查了两天才发现:EL2的页表配置错了,把设备内存映射成了普通内存。这就是架构知识不够扎实的代价。

总结一下这一节的核心:

  • ARM不造芯片,只卖IP,所以市面上有各种变种
  • Cortex-A/R/M分别对应应用、实时、微控制器场景,选型要谨慎
  • ARMv8-A不是简单的64位升级,异常模型和MMU都重构了
  • 架构版本直接影响MMU配置方式,后面章节会反复用到这些知识