先明确一点,MMU的主要工作只有一个, 就是把虚拟地址映射到物理地址。
ARM CPU 上的地址转换过程涉及3个概念:虚拟地址VA、 变换后的虚拟地址MVA、物理地址PA
没启动mmu时cpu核、cache、mmu、 外设都使用物理地址
启动mmu后,cup对外发出va;va完全有硬件自动转换成m va供cache、MMU使用转换成pa; 最后使用pa读写实际设备
如果VA<32M,use pid(read cp15‘s c13(具体在哪里?))to change to MVA:auto change
if(va<32M) then
mva=va|(pid<<25)
else
mva=va
虚拟地址到物理地址的转换过程
1.用一个确定公式进行转换
2.用表格存储虚拟地址对应的物理地址及其访问权限
TTB base代表一级页表的首地址,将它写入协处理器CP15( ARM920T的MMU和Cache都集成在CP15协处理器中 )的寄存器C2(称为页表基址寄存器)(固定?)即可, 一级页表的地址是16K对齐,使用[31:14]存储页表基址, [13:0]为0
一级页表使用4096个描述符来表示4GB空间, 每个描述符对应1MB的虚拟地址, 存储它对应的1MB物理空间的起始地址, 或者存储下一级页表的地址。使用MVA[31:20]来
索引一级页表(20-31一共12位,2^12=4096, 所以是4096个描述符),得到一个描述符, 每个描述符占4个字节。
*(((c2[31:14])+(MVA[31:20]>> 18))&0B00)=一级页表描述符
TTB的[31:14]=c2的[31:14] 可以理解为x86里面的段地址
TTB的[13:2]=MVA[31:20] 可以理解为x86里面的偏移地址
TTB的[1:0]=0b00
一级页表描述符格式如下:
根据一级描述符的最低两位[1:0],分为下面四种:
00=无效
01=粗页表基址
[31:10]=粗页表基址(了解为二级页表地址的段地址),[ 9:2](偏移地址,共2^8=259个,4kb/个)[1: 0]=0B01
10=段
[31:20]为段基址,、 此描述符低20位填充0后就是一块1MB物理地址空间的起始地址 。MVA[19:0],用来在这1MB空间中寻址。描述符的位[ 31:20]和MVA[19:0] 构成了这个虚拟地址MVA对应的物址
以段的方式进行映射时, 虚拟地址MVA到物理地址PA的转换过程如下:
①页表基址寄存器位[31:14]和MVA[31:20] 组成一个低两位为0的32位地址, MMU利用这个地址找到段描述符
②取出段描述符的位[31:20](段基址),它和MVA[ 19:0]组成一个32位的物理地址(这就是MVA对应的PA)
*(((c2[31:14])+(MVA[31:20]>> 18))&0B00)=段描述符
段描述符[31:20]+MVA[19:2]=PA
0B11=细表页
[31:12]细页表基址,[11:2](理解为偏移地址,2^ 10=1024个 1kb/个)共1mb
以大页(64KB),小页(4KB)或极小页(1KB) 进行地址映射时,需要用到二级页表,二级页表有粗页表、 细页表两种,二级页表描述符格式如下:
二级描述符最低两位:
0b00:无效
0b01:大页描述符
[31:16]为大页基址,此描述符的低16位填充0后就是一 块64KB物理地址空间的起始地址粗页表中的每个条目只能表示4 KB物理空间,如果大页描述符保存在粗页表中, 则连续16个条目都保存同一个大页描述符。类似的, 细页表中每个条目只能表示1KB的物理空间, 如果大页描述符保存在细页表中, 则连续64个条目都保存同一个大页描述符。
下面以保存在粗页表中的大页描述符为例,说明地址转化那过程
①页表基址寄存器[31:14]和MVA[31:20] 组成一个低两位为0的32位地址, MMU利用这个地址找到粗页表描述符
②取出粗页表描述符的[31:10](即粗页表基址), 它和MVA[19:12]组成一个低两位为0的32位物理地址, 通过这个地址找到大页描述符
③取出大页描述符的[31:16](即大页基址),它和MVA[ 15:0]组成一个32位的物理地址,即MVA对应的PA
步骤②和③中,用于在粗页表中索引的MVA[19:12]、 用于在大页内寻址的MVA[15:0]有重合的位[15:12] ,当位[15:12]从0b0000变化到0b1111时, 步骤②得到的大页描述符相同, 所以粗页表中有连续16个条目保存同一个大页描述符
*(((c2[31:14])+(MVA[31:20]>> 18))&0B00)=粗表描述符(一级描述符)
*((粗页表描述符[31:10]+(MVA[19:12]>> 10))&0xfffffffd)=大页描述符
((大页描述符[31:16]+MVA[15:0]))=PA
2^16=64kb
*(((c2[31:14])+(MVA[31:20]>> 18))&0B00)=粗表描述符(一级描述符)
*((粗页表描述符[31:10]+(MVA[19:16]>> 6))&0B00)=大页描述符
((大页描述符[31:16]+MVA[15:0]))=PA
0b10:小页描述符
[31:12]为小页基址(Small page base address),此描述符的低12位填充0后就是一块4kb(
从段、大页、小页、极小页的地址转换过程可知
①以段进行映射时,通过MVA[31:20]结合页表得到一段(
②以大页进行映射时,通过MVA[31:16]
③以小页进行映射时,通过MVA[31:12]
④以极小页进行映射时,通过MVA[31:10]
AP | S | R | 特权模式 | 用户模式 | 说明 |
00 | 0 | 0 | 无访问权限 | 无访问权限 | 任何访问将产生“Permission fault”异常 |
00 | 1 | 0 | 只读 | 无访问权限 | 在超级权限下可以进行读操作 |
00 | 0 | 1 | 只读 | 只读 | 任何写操作将产生”Permission fault“异常 |
00 | 1 | 1 | 保留 | - | - |
01 | x | x | 读/写 | 无访问权限 | 只允许在超级模式下访问 |
10 | x | x | 读/写 | 只读 | 在用户模式下进行写操作将产生"Permission fault"异常 |
11 | x | x | 读/写 | 读/写 | 在所有模式下允许任何访问 |
xx | 1 | 1 | 保留 | - | - |
4、Cache的作用
同样基于程序访问的局部性,
①写穿式(Write Through)
任一CPU发出写信号送到Cache的同时,也写入主存,
②回写式(Write Back)
数据一般只写到Cache,
Cache有以下两个操作:
①”清空“(clean):把Cache或Write buffer中已经脏的(修改过,但未写入主存)数据写入主存
②”使无效“(Invalidate):使之不能再使用,
S2C2440内置了指令Cache(ICaches)、
1)指令Cache(ICaches)
2)数据Cache(DCaches)
与ICaches不同,
DCaches被关闭时,CPU每次都去内存取数据。
DCaches被开启后,
通过下表可知DCaches和Write buffer在Ccr,Ctt,Btt各种取值下,如何工作,
Ctt and Ccr | Btt | DCaches、Write buffer 和主存的访问方式 |
0 | 0 | Non-cached,non-buffered(NCNB) 读写数据时都是直接操作主存,并且可以被外设中止; 写数据时不使用Write buffer,CPU会等待写操作完成; 不会出现Cache命中 |
0 | 1 | Non-Cached buffered(NCB) 读数据时都是直接操作主存; 不会出现Cache命中; 写数据时,数据线存入Write buffer,并在随后写入主存; 数据存入Write buffer后,CPU立即继续执行; 读数据时,可以被外设中止; 写数据时,无法被外设中止 |
1 | 0 | Cached,write-through(写通)mode 读数据时,如果Cache命中则从Cache中返回数据, 读数据时,如果Cache丢失则从读主存中返回数据,并导致“ 写数据时,数据先存入Write buffer,并在随后写入主存; 数据存入Write buffer后,CPU立即继续执行; 写数据时,如果Cache命中则新数据也写入Cache中; 写数据时,无法被外设中止 |
1 | 1 | Cached,write-back(写回) mode 读数据时,如果Cache命中则从Cache中返回数据, 读数据时,如果Cache丢失则从读主存中返回数据,并导致“ 写数据时,如果Cache丢失则将数据先存入Write buffer,存储完毕后CPu立即继续执行, 写数据时,如果Cache命中则在Cache中更新数据, 无论Cache命中与否,写数据都无法被外设中止 |
①清空DCaches,使主存数据得到更新(理解为剪切到主存)
②使无效ICaches,使CPU取指时重新读取主存
在实际编写程序时,要注意如下几点:
①开启MMU前,使无效ICaches,
②关闭MMU前,清空ICaches、DCaches,即将”
③如果代码有变,使无效ICaches,
④使用DMA操作可以被Cache的内存时,
⑤改变页表中地址映射关系时也要慎重考虑
⑥开启ICaches或DCaches时,
S3C2440除了ARM920T的CPU核心外,
{条件} 协处理器编码,协处理器操作码1,目的寄存器,源寄存器1,
{cond} p#,,Rd,cn,cm{,<<wbr>expression2>}
MRC
MCR
{cond}
p#
Rd
cn和cm
这个实例将开启MMU,并将虚拟地址0xA0000000-
将虚拟地址0xB0000000-
这个程序只使用一级页表,以段的方式进行地址映射,
程序分为两部分:第一部分的运行地址为0,
10
11
12 halt_loop:
13
#define WTCON
#define MEM_CTL_BASE
void disable_watch_dog(void)
{
}
void memsetup(void)
{
//=(volatile unsigned long *)MEM_CTL_BASE;//32bit
}
void copy_2th_to_sdram(void)
{
}
void create_page_table(void)
{
}
void mmu_init(void)
{
__asm__(
);
}
#define GPBDAT (*(volatile unsigned long *) 0xA0000014 ) //pa-0x56000014
#define GPB5_OUT (1<<(5*2))
#define GPB6_OUT (1<<(6*2))
#define GPB7_OUT (1<<(7*2))
#define GPB8_OUT (1<<(8*2))
static inline void wait(unsigned