ARM 是什么?
ARM(Advanced RISC Machines)处理器是一种精简指令集结构的高性价比、低功耗处理器,广泛用于各种嵌入式系统设计中。
RISC vs. CISC
- RISC: Reduced Instruction Set Computer
- CISC: Complex Instruction Set Computer
RISC 架构的特点
- 单周期执行:超过 95% 的指令可以在一个机器周期内完成
- 哈佛结构
- 简单的地址模式
- 方便使用硬连线(hardwiring)控制,而不使用微代码
- 使得汇编语言更难写
- 指令的大小是固定的:指令编解码更容易实现
- 优化了指令个数
- 减少了相关部件所需晶体管个数
- 汇编编程困难
- 使用了更多的寄存器
- Load/Store 指令结构:没有直接进行寄存器和内存运算的指令
- 更多的寄存器:ARM 有 16 个通用寄存器(R0 到 R15)
- 减少了对堆栈和内存的使用
流水线技术
流水线允许多个操作同时处理,而非顺序执行。
讲义上的描述挺多的,我就不抄了。简单理解,流水线技术基于以下事实:
- 一个操作可以被分解为多个步骤:比如取指(IF)、译码(ID)、执行(EX)、访存(MEM)、写回(WB)
- 上述几个步骤在一定程度上可以独立工作,即可以同时进行
- 那在统一的时钟驱动下,可以按顺序同时进行多个操作,只不过这些操作分别处于不同的步骤
为了充分利用流水线,往往需要:
- 使用简单的代码:避免频繁的跳转
- 使用简单的数据结构:保持数据顺序、相邻和连续分布
“前沿”技术:
- 超标量——同时进行多条流水线
- 乱序执行
Cortex-A8 处理器
架构
- 指令读取单元
- 指令译码(解码)单元
- 指令执行单元
- L2 缓存单元(L2 Cache)
- NEON 媒体处理引擎
- ETM 单元
- 外部接口
- ……
工作模式
据说下表比较重要:
| 处理器模式 | 模式标识符 | 备注 |
|---|---|---|
| 用户模式 | usr | 正常程序执行模式 |
| 系统模式 | sys | 使用和用户模式相同的寄存器组,用于运行特权级操作系统任务 |
| 管理模式 | svc | 系统复位或软件中断时进入该模式,是供操作系统使用的一种保护模式 |
| 外部中断模式 | irq | 低优先级中断发生时进入该模式,常用于普通的外部中断处理 |
| 快速中断模式 | fiq | 高优先级中断发生时进入该模式,常用于高速数据传输和通道处理 |
| 数据访问中止模式 | abt | 当存取异常时进入该模式,用于虚拟存储和存储保护 |
| 未定义指令中止模式 | und | 当执行未定义指令时进入该模式,用于支持硬件协处理器 |
| 安全监控模式 | mon | 可在安全模式和非安全模式下运行 |
对于各种工作模式,相关描述如下:
- 除了用户模式外,剩下的都是特权模式
- 系统模式不能由任何异常进入,有与用户模式完全相同的寄存器
- 除了上述两种模式外,剩下的都是异常模式
- 它们既可以由程序切换进入,也可以在发生特定的异常中断时进入
- 每一种异常模式都有一组专用的寄存器,保证在进入异常模式时用户模式下的寄存器的数据不被破坏
- 大多数情况下,应用程序运行在用户模式下
- 它们不能访问受操作系统保护的系统资源,也不能直接进行处理器工作模式的切换
- 在需要进行工作模式切换时,应用程序可以产生异常处理
- 在异常处理过程中进行工作模式切换,由操作系统控制整个系统资源的使用
工作状态
Cortex-A8 处理器是 32 位处理器。
- ARM 指令集:32 位
- 兼容 16 位 Thumb-2 指令集和数据类型
3 种工作状态,由程序状态寄存器(CPSR)的 T 位和 J 位决定:
| 工作状态 | T 位 | J 位 | 备注 |
|---|---|---|---|
| ARM 状态 | 0 | 0 | 执行 32 位的字对齐的 ARM 指令集指令 |
| Thumb 状态 | 1 | 0 | 执行 16 位或 32 位半字对齐的 Thumb-2 指令集指令 |
| ThumbEE 状态 | 1 | 1 | 执行为动态产生目标而设计的 16 位或 32 位半字对齐的 Thumb-2 指令集的变体 |
相关描述如下:
- ARM 指令必须在 ARM 状态下执行
- Thumb 指令必须在 Thumb 状态下执行
- ARM 处理器可以在两种状态下切换
- 只要遵循 ATPCS 调用规则,ARM 子程序和 Thumb 子程序之间可以互相调用
- ARM 状态和 Thumb 状态之间的切换并不影响处理器工作模式和寄存器组的内容
- 处理器复位后开始执行代码时,处于 ARM 状态
- 异常处理必须在 ARM 状态下
存储器管理
Cortex-A8 处理器对“字”的定义如下:
- 字节(Byte):8 位
- 半字(Half word):16 位
- 字(Word):32 位
- 双字(Double word):64 位
可以看到它与我们熟悉的 x86 架构的定义存在出入。
- ARM 的无符号整数用原码表示,有符号整数用补码表示
- ARM 的二进制浮点数据类型遵从 IEEE 754 标准
- 向量浮点运算单元(VFP)的一些版本还支持半精度浮点数(16 位)
数据对齐
ARM 的体系结构将存储器看成:
- 从 0x00000000 地址开始的按字节编码的线性存储结构
- 每个字节都有对应的地址编码
为了提高存储系统的读写效率,数据往往会进行对齐处理:
- 以字为单位,按 4 字节对齐,地址最末两位为 00
- 以半字为单位,按 2 字节对齐,地址最末一位为 0
- 以字节为单位,按 1 字节对齐
这件事情在 C 结构体中可以得到生动的体现,CSAPP 的第三章也提到过这件事。
大/小端存储模式
- 大端模式(Big-endian)
- 被存放字数据的高字节存放在存储地址的低地址中
- 被存放字数据的低字节存放在存储地址的高地址中
- 小端模式(Little-endian)
- 被存放字数据的高字节存放在存储地址的高地址中
- 被存放字数据的低字节存放在存储地址的低地址中
比如说,某个 32 位无符号整数 0x12345678,如果从左到右地址连续增加,那么该整数的大端存储模式为
12 34 56 78
小端存储模式为
78 56 34 12
至于到底哪个模式更好就见仁见智了,不过目前好像在主机上小端序用得多,网络传输过程中可能会遇到大端序。
Cortex-A8 处理器支持大端和小端两种存储模式
- 支持混合大小端模式和非对齐数据访问
- 通过硬件的方式设置(没有提供软件的方式)端模式
存储器系统的层次结构
- 寄存器:包含在 CPU 内部,用于指令执行时的数据存放
- Cache:高速缓存,暂存 CPU 正在使用的指令和数据
- 主存储器:程序执行代码和数据的存放区(内存)
- 辅助存储器:“硬盘”
大体上,整个存储结构又可以被看成是两个层次:
- 主存-辅存层次
- Cache-主存层次
寄存器组
Cortex-A8 处理器共有 40 个 32 位寄存器,包括 33 个通用寄存器和 7 个状态寄存器。
R0~R14用于一般数据存储R15用于程序计数器(PC)- 1 个
CPSR(当前程序状态寄存器),用户模式和系统模式共用一组 - 6 个
SPSR(备份程序状态寄存器),每个异常模式私有一组 R0~R7为不分组的通用寄存器,所有模式共用;R8~R15为分组的通用寄存器,在不同模式下可能有独有的物理寄存器- 异常模式拥有一些私有寄存器组,其中
- fiq 模式有 7 个(
R8_fiq~R14_fiq) - 其他模式均有 2 个 (
R13_<mode>、R14_<mode>),<mode>为当前模式名
- fiq 模式有 7 个(
R13~R15一般有特殊功能R13常用作堆栈指针(SP)R14常用作子程序链接寄存器(LR):在执行BL和BLX指令、发射中断和异常或子程序调用时,R14保存返回地址R15用于记录程序当前的运行地址:ARM 处理器每执行一条指令,PC 都会增加 4 字节(Thumb 模式为 2 字节);分支指令等也会改变 PC 的值。
对于状态寄存器,需要说明:
- 程序状态寄存器的主要功能是
- 保存最近执行的算术或逻辑运算的信息
- 控制中断的允许或禁止
- 设置处理器的工作模式
- 32 为状态寄存器被分成 4 个域
- 标志位域
- 状态域
- 扩展域
- 控制域
- 有 4 个条件标志位,基于程序的算术和逻辑指令的执行结果
- N(Negative):N=1 表示运算的结果为负数,否则为正数或零
- Z(Zero):Z=1 表示运算的结果为零
- C(Carry):在加法指令中,C=1 表示结果产生了进位;减法指令中,C=0 表示结果产生了借位
- V(oVerflow):对加/减法运算指令,当操作数和运算结果为二进制补码表示的有符号数时,V=1 表示符号位溢出
- 中断屏蔽位
- I=1,irq 中断被屏蔽
- F=1,fiq 中断被屏蔽
- 状态控制位(工作状态部分提到过)
- T=0,处理器处于 ARM 状态
- T=1,处理器处于 Thumb 状态
协处理器 CP15
实现对存储系统的管理通常使用协处理器 CP15,也被称为系统控制协议处理器
- ARM 处理器支持 16 个协处理器
- 程序在执行过程中,每个协处理器忽略属于 ARM 处理器和其他协处理器的指令;当一个协处理器不能执行属于它的指令时,会产生未定义指令异常中断
- CP15 完成大部分的存储器管理
- 在一些没有标准存储管理的系统中,CP15 不存在
- CP15 有 16 个 32 位寄存器,编号 0 ~ 15
- 某些编号的寄存器可能对应多个物理寄存器,在指令中用特定的标志位来区分,类似于 ARM 的寄存器
- 处于不同的处理器模式时,ARM 某些寄存器可能不同
内存管理单元 MMU
面对一些复杂、多任务的嵌入式应用时,尝使用嵌入式操作系统来管理整个系统和任务的运行。高级的嵌入式操作系统都带有内存管理单元(MMU)来管理每个任务各自的存储空间。
当应用程序的规模不断增大,超过了内存的增长速度,以至于内存存放不下应用程序时,需要采用虚拟内存技术。
MMU 的重要任务是让每个任务都运行在各自的虚拟存储空间中,
- 它作为转换器,将程序和数据的虚拟地址转换成实际的物理地址,也就是实现虚拟存储空间到物理存储空间的映射
- 其他功能还包括:
- 存储器访问权限的控制,提供硬件机制的内存访问授权
- 设置虚拟存储空间缓冲的特性
高速缓冲存储器 Cache
Cache 是一种小容量、高速度的存储器,用于处理器与主存之间存放当前被使用的主存内容,以减少访问主存的等待时间
Cache 一般和写缓存一起使用
异常处理
异常是 ARM 处理器处理外部异步事件的一种方法,有时也称为中断。若有多个异常发生,处理器将根据异常中断优先级来处理这些异常。在 ARM 体系结构中有 7 种异常中断:
| 异常类型 | 处理器模式 | 优先级 | 说明 |
|---|---|---|---|
| 复位异常(Rest) | 管理模式 | 1 | REST 复位脚有效时进入该异常,常用在系统加点时和系统复位时 |
| 未定义指令异常(Undefined Interrupt) | 未定义指令模式 | 6 | ARM 处理器或协处理器遇到不能处理的指令产生该异常,可利用该异常进行软件仿真 |
| 软件中断异常(SWI) | 管理模式 | 6 | 由 SWI 指令产生,可用于用户模式下的程序调用特权操作 |
| 指令预取中止异常(Prefetch Abort) | 未定义指令中止模式 | 5 | 当预取指令不存在或该地址不允许当前指令访问时产生该异常,常用于虚拟内存和存储器保护 |
| 数据访问中止异常(Data Abort) | 数据访问中止模式 | 2 | 数据访问指令的目标地址不存在或该地址不允许当前指令访问时产生该异常,常用于虚拟内存和存储器保护 |
| 外部中断异常(IRQ) | 外部中断模式 | 1 | 处理器的外部中断请求引脚有效,且 CPSR 的 I 位为 0 时,产生该异常,常用于系统外设请求 |
| 快速中断异常(FIQ) | 快速中断模式 | 1 | 该异常是为了支持数据传送或通道处理而设计的,处理器的快速中断请求引脚有效,且 CPSR 的 F 位为 0 时,产生该异常。 |
异常向量和表
异常发生时,处理器会将 PC 寄存器设置为一个特定的存储器地址,这些特定的存储器地址称为异常向量:
- 所有异常的异常向量被集中放在程序存储器的一个连续地址空间中,称为异常向量表
- 每个异常向量只占 4 个字节,异常向量处是一些跳转指令,跳转到对应的异常处理程序
- 通常存储器地址映射地址
0x00000000是为异常向量表保留的- 某些嵌入式中在系统配置使能时,低端的异常向量表可以选择映射到特定的高端地址
0xFFFF0000处 - Cortex-A8 处理器支持通过设置协处理器 CP15 的 C12 寄存器将异常向量表的首地址设置在任意地址
- 某些嵌入式中在系统配置使能时,低端的异常向量表可以选择映射到特定的高端地址
异常响应过程
异常(中断)响应大致可以分为以下几个步骤:
- 保护断点,即保存下一个将要执行的指令的地址,就是把这个地址送入堆栈;
- 寻找中断入口,根据不同的中断源所产生的中断,查找不同的入口地址;
- 执行中断处理程序;
- 中断返回,执行完中断指令后,就从中断处返回到主程序,继续执行。
ARM 异常处理流程
- 进入与特定的异常相应的运行模式
- 将
CPSR寄存器的值保存到将要执行的异常中断各自对应的SPSR_<mode>中,以实现对处理器当前运行状态、中断屏蔽和各标志位的保护 - 将引起异常指令的下一条指令的地址存入相应的链接寄存器 LR(
R14_<mode>),以便程序在异常处理结束返回能正确地返回到原来地程序处继续向下执行 - 设置
CPSR寄存器的低 5 位,使处理器进入相应的工作模式
- 设置 I=1,以禁止 IRQ 中断;如果进入复位模式或 FIQ 模式,还要设置 F=1 以禁止 FIQ 中断
- 根据异常类型,将异常向量地址强制复制给程序计数器 PC,以便执行相应的异常处理程序
- 每种异常模式对应两个寄存器
R13_<mode>和R14_<mode>,分别代表堆栈指针和断点地址,这一点前文已经提及
- 每种异常模式对应两个寄存器
- 除了复位异常,其他异常处理完后必须返回到原来程序的断点处继续执行
- 特别地,复位异常发生后,由于系统自动从
0x00000000开始重新执行程序,因此复位异常处理程序执行完后无须返回
- 特别地,复位异常发生后,由于系统自动从
- ARM 处理器从异常处理程序中返回的过程如下:
- 恢复原来被保存的用户寄存器
- 将
CPSR_<mode>寄存器的值复制到CPSR中,以恢复被中断的程序工作状态 - 根据异常类型将 PC 寄存器的值恢复成断点地址(不一定等于 LR),以执行原来被中断打断的程序
- 清除
CPSR中的中断屏蔽标志位 I 和 F,开放外部中断和快速中断
Cortex-A8 处理器 S5PV210 的中断机制
S5PV210 集成了 4 个向量中断控制器(Vector Interrupt Controller,VIC)PL192 和 4 个 TrustZone 中断控制器(TVIC)SP890,支持 93 个中断源(每个 LP142 支持 32 个中断源)
- 向量中断控制器是用来处理多个中断源的外围设备
- Cortex-A8 提供了 2 中中断模式: FIQ 模式和 IRQ 模式
- 所有的中断源在中断请求时都要确定使用哪一种中断模式