文章目录
- 前言
- 一、 ARM中用于存储管理的控制协处理器CP15
- 1、 访问CP15寄存器的指令
- 2、 CP15的寄存器
- 二、 存储器管理单元MMU
- 1、 MMU的由来
- 2、 禁止/使能MMU
- 3、 MMU中地址变换过程
前言
本文是学习《ARM体系结构与编程》(杜春雷 著)的读书笔记。该书以 ARM v6 之前的体系架构为基础,内容相对较早,但对初学者仍有不少可借鉴之处。文中结合了书中的讲解与网络资料,整理成笔记,希望能与大家共同进步。
一、 ARM中用于存储管理的控制协处理器CP15
1、 访问CP15寄存器的指令
- 指令与语法格式
| 指令 | 说明 | 语法格式 |
|---|---|---|
| MCR | 将ARM寄存器中的数据传送到协处理器寄存器中 | MCR{<cond>} p15, <opcode_1>, <Rd>, <CRn>, <CRm>, {<opcode_2>} |
| MRC | 将协处理器寄存器中的数据传送到ARM寄存器中 | MRC{<cond>} p15, <opcode_1>, <Rd>, <CRn>, <CRm>, {<opcode_2>} |
注:这两条指令只能在系统模式下使用,否则会触发未定义指令异常。在用户模式下,可以由操作系统定义一些 SWI 调用,通过 SWI 调用间接完成相应功能。
- 指令编码格式及说明
| 31~28 | 27~24 | 23~21 | 20 | 19~16 | 15~12 | 11~8 | 7~5 | 4 | 3~0 |
|---|---|---|---|---|---|---|---|---|---|
| cond | 1110 | 0 0 0 (opcode_1) | 0(MCR) 1(MRC) | CRn | Rd | cp_num | opcode_2 | 1 | CRm |
说明:
<cond>:指令执行的条件码。忽略条件码时,指令无条件执行。
<opcode_1>:协处理器行为操作码。对于 CP15 来说,<opcode_1> 永远为 0b000,否则结果未知。
<Rd>:不能是 R15/PC,否则结果未知。
<CRn>:作为目标寄存器的协处理器寄存器,编号为 C0~C15。
<CRm>:附加的目标寄存器或源操作数寄存器。如果不需要设置附加信息,应将 CRm 设置为 C0,否则结果未知。
<opcode_2>:提供附加信息,例如寄存器的版本号或访问类型,用于区分同一编号下的不同物理寄存器。可以省略 <opcode_2>,或将其设置为 0,否则结果未知。
2、 CP15的寄存器
- CP15可以有16个32位的寄存器:
| 寄存器编号 | 基本作用 | 在MMU中的作用 | 在PU中的作用 |
|---|---|---|---|
| 0 | ID编码(只读) | ID编码和cache类型 | |
| 1 | 控制位(可读写) | 各种控制位 | |
| 2 | 存储保护和控制 | 地址转换表基地址 | Cachability的控制位 |
| 3 | 存储保护和控制 | 域访问控制位 | Bufferablity控制位 |
| 4 | 存储保护和控制 | 保留 | 保留 |
| 5 | 存储保护和控制 | 内存失效状态 | 访问权限控制位 |
| 6 | 存储保护和控制 | 内存失效地址 | 保护区域控制 |
| 7 | 高速缓存和写缓存 | 高速缓存和写缓存控制 | |
| 8 | 存储保护和控制 | TLB控制 | 保留 |
| 9 | 高速缓存和写缓存 | 高速缓存锁定 | |
| 10 | 存储保护和控制 | TLB锁定 | 保留 |
| 11 | 保留 | ||
| 12 | 保留 | ||
| 13 | 进程标识符 | 进程标识符 | |
| 14 | 保留 | ||
| 15 | 因不同设计而异 | 因不同设计而异 | 因不同设计而异 |
注:高亮的标识的寄存器为与MMU操作相关的。
- 寄存器C0:
- 当操作码opcode_2 = 0,C0为存放ARM处理器信息
ARM7之后的处理器,其主标识符的编码格式:
| 31~24 | 23~20 | 19~16 | 15~4 | 3~0 |
|---|---|---|---|---|
| 厂商决定 | 产品子编号 | ARM体系版本号 | 产品主编号 | 处理器版本号 |
- 当opcode_2 = 1,C0存放Cache属性信息
| 31~29 | 28~25 | 24 | 23~12 | 11~0 |
|---|---|---|---|---|
| 000 | 属性 | 指令和数据Cache是否分开 | 数据Cache相关属性 | 指令Cache相关属性 |
[23 : 12]用于定义数据cache的属性,[11 : 0]用于定义指令cache的属性
| 11~9 | 8~6 | 5~3 | 2 | 1~0 |
|---|---|---|---|---|
| 000 | 容量 | Cache相联特性 | M | 块大小 |
- 控制寄存器C1:
功能主要包括:
- 禁止/使能MMU以及其他的与存储系统相关的功能;
- 配置存储系统以及ARM处理器中的相关部分的工作方式。
指令格式如下所示:
MRC p15,0, R0, C1, C0{,0};将CP15的寄存器C1的值读到R0中 MCR p15,0, R0, C1, C0{,0};将R0的值写到CP15的寄存器C1中- 寄存器C1的编码格式及含义
| 31~16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| SBZP/UNP | L4 | RR | V | I | Z | F | R | S | B | L | D | P | W | C | A | M |
| 控制位 | 含义 |
|---|---|
| M | 0:禁止MMU或者PU;1:使能MMU或者PU |
| A | 0:禁止地址对齐检查;1:使能地址对齐检查 |
| C | 0:禁止数据/整个cache;1:使能数据/整个cache |
| W | 0:禁止写缓冲;1:使能写缓冲 |
| P | 0:异常中断处理程序进入32位地址模式;1:异常中断处理程序进入26位地址模式 |
| D | 0:禁止26位地址异常检查;1:使能26位地址异常检查 |
| L | 0:选择早期中止模型;1:选择后期中止模型 |
| B | 0:little endian;1:big endian |
| S | 在基于MMU的存储系统中,本位用作系统保护 |
| R | 在基于MMU的存储系统中,本位用作ROM保护 |
| F | 0:由生产商定义 |
| Z | 0:禁止跳转预测功能;1:使能跳转预测指令 |
| I | 0:禁止指令cache;1:使能指令cache |
| V | 0:选择低端异常中断向量0x00x1c;1:选择高端异常中断向量0xffff00000xffff001c |
| RR | 0:常规的cache淘汰算法,如随机淘汰;1:预测性淘汰算法,如round-robin淘汰算法 |
| L4 | 0:保持ARMv5以上版本的正常功能;1:将ARMv5以上版本与以前版本处理器兼容,不根据跳转地址的bit[0]进行ARM指令和Thumb状态切换:bit[0]等于0表示ARM指令,等于1表示Thumb指令 |
| [31:16] | 保留,应为SBZP/UNP |
二、 存储器管理单元MMU
在ARM系统中,MMU主要完成以下工作:
- 虚拟存储空间到物理存储空间的映射。
- 存储器访问权限的控制。
- 设置虚拟存储空间的缓冲的特性。
MMU 的实现需要引入页表(translate table)机制。页表存储在内存中,表中的每一行对应虚拟存储空间的一个页,这样的一行称为地址变换条目。系统通常提供一个寄存器来保存页表的基地址(在 ARM 中,由系统控制协处理器 CP15 的C2 寄存器保存页表基地址)。从虚拟地址到物理地址的变换过程,本质上就是查询页表的过程。
为了解决内存访问速度的问题,MMU 采用了类似 cache 的方式,引入快表 TLB(translation lookaside buffer)机制,用一小块快速的存储空间(通常为 8~16 个字)来存放当前需要访问的地址变换条目。-C8寄存器用来控制清除TLB内容的相关操作:当内存中页表内容改变,或者通过修改CP15的C2寄存器使用新的叶表时,TLB中的内容需要全部清除。
- C10寄存器控制TLB内容的锁定:MMU可以将某些地址变换条目锁定(locked down)在TLB中,从而使得进行与该地址变换条目相关的地址变换速度保持很快。
- C3寄存器控制与域相关的属性的配置:MMU可以将整个存储空间分为最多16个域(domain)。
- C5和C6寄存器分别处理内存失效时的状态指示和失效的地址。
注:我们在程序中使用的变量和函数都有各自的地址,在程序被编译后,这些地址就成了指令中的地址,指令中的地址就成了CPU执行单元发出的内存地址,所以在启用MMU的情况下, 程序中使用的地址均是虚拟内存地址,都会引发MMU进行查表和地址转换操作。
内存保护机制
处理器一般有用户模式(User Mode)和特权模式(privileged Mode)之分。操作系统可以在页表中设置每个页表访问权限,有些页表不可以访问,有些页表只能在特权模式下访问,有些页表在用户模式和特权模式下都可以访问,同时,访问权限又分为可读、可写和可执行三种。这样设定之后,当CPU要访问一个VA(Virtual Address)时,MMU会检查CPU当前处于用户模式还是特权模式,访问内存的目的是读数据、写数据还是取指令执行,如果与操作系统设定的权限相符,则允许访问,把VA转换成PA,否则不允许执行,产生异常(Exception)。段错误是这样产生的:
- 用户程序要访问的一个VA,经MMU检查无权访问。
- MMU产生一个异常,CPU从用户模式切换到特权模式,跳转到内核代码中执行异常服务程序。
- 内核把这个异常解释为段错误,把引发异常的进程终止掉。
1、 MMU的由来
以相对有限的内存空间运行远大于空间的程序代码
在许多年以前,人们还在使用 DOS 或一些古老的操作系统,那时内存很小,应用程序也很小,把程序全部装入内存基本就能满足需要。随着科技的发展,图形界面以及其他更复杂的应用不断出现,内存已经无法容纳这些应用程序了。通常的解决办法是把程序分割成多个覆盖块:覆盖块 0 最先运行,运行结束后再调用另一个覆盖块。虽然这些操作由操作系统完成,但需要程序员自己分割程序,效率非常低。于是,人们提出了虚拟存储器(virtual memory)的方法。虚拟存储器的基本思想是:程序、数据和堆栈的总大小可以超过内存空间的大小,操作系统只把当前正在运行的部分保存在内存中,未使用的部分保存在磁盘上。例如,一个 16MB 的程序运行在只有 4MB 内存的机器上,操作系统可以决定哪 4MB 内容留在内存中,并在需要时在内存与磁盘之间交换程序代码,这样16MB 的代码就可以运行在 4MB 的机器中了。注意:这里已经包含了虚拟地址和物理地址的概念。
2、 禁止/使能MMU
CP15的寄存器C1的位[0]控制禁止/使能MMU。0禁止1使能。
- 禁止/使能MMU时应注意的问题
- 使能MMU之前,要在内存中建立好页表,同时CP15中的各相关寄存器必须完成初始化。
- 如果使用的不是平板存储模式,在禁止/使能MMU时,虚拟地址和物理地址的对应关系会发生改变,这时应该清除cache中的当前地址变换条目。
- 如果完成禁止/使能MMU的代码的物理地址和虚拟地址不相同,则禁止/使能MMU时将造成很大麻烦,因此完成禁止/使能MMU的代码的物理地址和虚拟地址最好相同。
3、 MMU中地址变换过程
ARM支持的存储块大小:
- 段:大小为1M的存储块
- 大页:大小为64KB的存储块
- 小页:大小为4KB的存储块
- 极小页:大小为1KB的存储块
在MMU中采用下面两级页表实现:
- 一级页表中包含有以段为单位的地址变换条目以及指向二级页表的指针。一级页表实现的地址映射粒度较大。
- 二级页表中包含以大页和小页为单位的地址变换条目。其中,一种类型的二级页表好包含有以极小页为单位的地址变换条目
通常,以段为单位的地址变换过程只需要一级页表。而以页为单位的地址变换过程还需要二级页表。
- 基于段的地址变换过程
- 大页地址变换过程(粗粒度)
- 小页地址变换过程(粗粒度)
- 极小页地址变换过程(细粒度)
- 选择页表大小的优点:
- 较小的页:
- 没有外碎片,内部碎片少,且每个页碎片不超过页的大小,空间利用率高。
- 较大的页或段:
- 页表规模小,页表占用内存较小。
- 单个页面覆盖范围较大,TLB命中率高。
- 较小的页: