一直想写一篇关于MMU和cache的文章,但是又不敢随意下笔,毕竟感觉对这个东西理解不够透彻,最近刚好遇到两个关于这方面的问题,决定还是先把网上的一些介绍和自己的理解整理一篇博文。
1.1 MMU
1.1.1 名词解释
PGD(Page Global Directory):全局页表
PUD(Page Upper Directory):顶层页表,一般嵌入式系统没有。
PMD(Page Middle Directory):中间层页表,一般嵌入式系统没有。
PTE(Page Table Entry):页表
TLB(Translation Lookaside Buffers): 即转换快表,又简称快表,可以理解为MMU内部专用的存放页表的cache,保存着最近使用的PTE。
1.1.2 映射方式
32bit的Linux采用三级映射:PGD-->PMD-->PTE,64bit的Linux采用四级映射:PGD-->PUD-->PMD-->PTE,多了个PUD。在ARM32 Linux采用两层映射,省略了PMD,除非在定义了CONFIG_ARM_LPAE才会使用3级映射。在ARM32架构中,可以按段(section)来映射,这是采用单层映射模式。使用页面映射需要两层映射结构,页面可以是64KB或4KB大小。
如下图所示,如果采用页表映射的方式,段映射表就变成一级映射表(Linux中称为PGD),其页表项提供的不再是物理地址,而是二级页表的基地址。32位虚拟地址的高12位(bit[31:20])作为访问一级页表的索引值,找到相应的表项,每个表项指向一个二级页表。
以虚拟地址的次8位(bit[19:12])作为访问二级页表的索引值,得到相应的页表项,从这个页表项中找到20位的物理页面地址。最后将这20位物理页面地址和虚拟地址的低12位拼凑在一起,得到最终的32位物理地址。这个过程在ARM32架构中由MMU硬件完成,软件不需要接入。
1.1.3 CPU访问内存时的硬件操作顺序
各步骤在图中有对应的标号:
1 CPU内核(图中的ARM)发出VA请求读数据,TLB(translation lookaside buffer)接收到该地址,那为什么是TLB先接收到该地址呢?因为TLB是MMU中的一块高速缓存(也是一种cache,是CPU内核和物理内存之间的cache),它缓存最近查找过的VA对应的页表项,如果TLB里缓存了当前VA的页表项就不必做translation table walk了,否则就去物理内存中读出页表项保存在TLB中,TLB缓存可以减少访问物理内存的次数。
2 页表项中不仅保存着物理页面的基地址,还保存着权限和是否允许cache的标志。MMU首先检查权限位,如果没有访问权限,就引发一个异常给CPU内核。然后检查是否允许cache,如果允许cache就启动cache和CPU内核互操作。
3 如果不允许cache,那直接发出PA从物理内存中读取数据到CPU内核。
4 如果允许cache,则以VA为索引到cache中查找是否缓存了要读取的数据
,如果cache中已经缓存了该数据(称为cache hit)则直接返回给CPU内核,如果cache中没有缓存该数据(称为cache miss),则发出PA从物理内存中读取数据并缓存到cache中,同时返回给CPU内核。但是cache并不是只去CPU内核所需要的数据,而是把相邻的数据都去上来缓存,这称为一个cache line。ARM920T的cache line是32个字节,例如CPU内核要读取地址0x30000134~0x3000137的4个字节数据,cache会把地址0x30000120~0x3000137(对齐到32字节地址边界)的32字节都取上来缓存。
5. ARM920T支持多种尺寸规格的页表
ARM体系结构最多使用两级页表来进行转换,页表由一个个条目组成,每个条目存储一段虚拟地址对应的物理地址及访问权限,或者下一级页表的地址。S3C2443最多会用到两级页表,已段(section,大小为1M)的方式进行转换时只用到一级页表,以页(page)的方式进行转换时用到两级页表。而页的大小有3种:大页(large pages,64KB),小页(small pages,4KB)和极小页(tiny pages,1KB)。条目也成为描述符,有段描述符、大页描述符、小页描述符和极小页描述符,分别保存段、大页、小页和极小页的起始物理地址。
1.1.4 页表项结构
上图就是页目录项和页表项的格式。可以看出,由于页表或者页的物理地址都是4KB对齐的(低12位全是零),所以上图中只保留了物理基地址的高20位(bit[31:12])。低12位可以安排其他用途。
【P】:存在位。为1表示页表或者页位于内存中。否则,表示不在内存中,必须先予以创建或者从磁盘调入内存后方可使用。
【R/W】:读写标志。为1表示页面可以被读写,为0表示只读。当处理器运行在0、1、2特权级时,此位不起作用。页目录中的这个位对其所映射的所有页面起作用。
【U/S】:用户/超级用户标志。为1时,允许所有特权级别的程序访问;为0时,仅允许特权级为0、1、2的程序访问。页目录中的这个位对其所映射的所有页面起作用。
【PWT】:Page级的Write-Through标志位。为1时使用Write-Through的Cache类型;为0时使用Write-Back的Cache类型。当CR0.CD=1时(Cache被Disable掉),此标志被忽略。对于我们的实验,此位清零。
【PCD】:Page级的Cache Disable标志位。为1时,物理页面是不能被Cache的;为0时允许Cache。当CR0.CD=1时,此标志被忽略。
【A】:访问位。该位由处理器固件设置,用来指示此表项所指向的页是否已被访问(读或写),一旦置位,处理器从不清这个标志位。这个位可以被操作系统用来监视页的使用频率。
【D】:脏位。该位由处理器固件设置,用来指示此表项所指向的页是否写过数据。
【PS】:Page Size位。为0时,页的大小是4KB;为1时,页的大小是4MB(for normal 32-bit addressing )或者2MB(if extended physical addressing is enabled).
【G】:全局位。如果页是全局的,那么它将在高速缓存中一直保存。当CR4.PGE=1时,可以设置此位为1,指示Page是全局Page,在CR3被更新时,TLB内的全局Page不会被刷新。
【AVL】:被处理器忽略,软件可以使用。
参考博文:
(54条消息) MMU和cache详解(TLB机制)_Keep Fighting!-CSDN博客