1. mmu产生原因
许多年以前,当人们还在使用DOS或是更古老的操作系统的时候,计算机的内存还非常小,一般都是以K为单位进行计算,相应的,当时的程序规模也不大,所以内存容量虽然小,但还是可以容纳当时的程序。但随着图形界面的兴起还用用户需求的不断增大,应用程序的规模也随之膨胀起来,终于一个难题出现在程序员的面前,那就是应用程序太大以至于内存容纳不下该程序,通常解决的办法是把程序分割成许多称为覆盖块(overlay)的片段。覆盖块0首先运行,结束时他将调用另一个覆盖块。虽然覆盖块的交换是由OS完成的,但是必须先由程序员把程序先进行分割,这是一个费时费力的工作,而且相当枯燥。人们必须找到更好的办法从根本上解决这个问题。不久人们找到了一个办法,这就是虚拟存储器(virtual memory).虚拟存储器的基本思想是程序,数据,堆栈的总的大小可以超过物理存储器的大小,操作系统把当前使用的部分保留在内存中,而把其他未被使用的部分保存在磁盘上比如对一个16MB的程序和一个内存只有4MB的机器,OS通过选择,可以决定各个时刻将哪4M的内容保留在内存中,并在需要时在内存和磁盘间交换程序片段,这样就可以把这个16M的程序运行在一个只具有4M内存机器上了。而这个16M的程序在运行前不必由程序员进行分割。
2.虚拟存储器
虚拟存储器(VP),是由N个字节组成的,它存在于磁盘上(注意,是磁盘上,不是存储器内存上)。另外物理存储器和虚拟存储器都是用页来作为磁盘和内存的传输单元。左边每一行为一页(虚拟页),右边每一行为一个页框。p:一般为12,也就是2的12次方为4KB。
注意VP上的的页有3种状态:
a. 未分配的。VM系统还未创建的页。
b.缓存的。当前缓存再内存中。
c.未缓存的。未缓存再内存中。
3.缓存机制
读写速度:
SRAM = 10 DRAM, DRAM = 100 000 disk.
比如:
cpu访问磁盘中的数据,就把磁盘中的部分数据缓存到DRAM中,然后从DRAM中读取操作,这样访问速度提高不少。
4.页表
如上面缓存,虚拟存储器系统要知道虚拟页是否存储在DRAM中,如果没有hit,就需要牺牲DRAM中的一个虚拟页,然后从磁盘中读取新的虚拟页缓存到DRAM中。下图表示一个页表条目(page Table Entry)
a.有效位表示:物理页框是否映射到虚拟页中。
按照上述概念,应该能理解哪些页未分配(vp0,vp5),未缓存(vp3,vp6),缓存的(1,2,7,4)。
5.页命中与缺页
1.如果我们访问VP2,因为VP2的虚拟页已经缓存在DRAM中(PTE2 valid),所以页命中了。大家相安无事。
2.当cpu访问VP3,发现PTE3的有效位为0,判断虚拟存储器未缓存在DRAM中,因此触发一个缺页异常。此时就需要选择一个牺牲页(用的几率比较小的页,比如VP4),如果牺牲页内容发生改变,需要从DRAM回写到磁盘中。然后从磁盘拷贝VP3到DRAM中并更新PTE3(有效位为1).此时就可以正常访问VP3了。
6.进程角度看虚拟存储器
每个进程都有独立的页表,也就是一个独立的虚拟地址空间(linux 每个进程都有0-3G的用户空间,和3G-4G的内核空间)。
进程i 的 VP1 映射到 PP2,VP2映射到7.
进程j的VP1映射到PP7(共享内存),VP2映射到10.
这样优势很明显,相当于每个进程都有独立的地址空间。且允许每个进程使用同样的存储器映像格式(如下图),而不用管代码段等实际放在哪个物理地址上。32位操作系统总是从虚拟地址0x08048000开始。
7.PTE增加保护机制
每次CPU要访问一个虚拟地址,地址翻译硬件都会读出一个PTE,所以在PTE上加上访问权限是非常简单的。
SUP:表示超级用户
READ:读权限。
WRITE:写权限。
如果没有访问权限的话进行操作,就会出现段错误。
8.地址翻译
地址翻译:N元素(虚拟地址)到M元素(物理地址)之间的映射。
1.CPU的页表基址寄存器,指示当前页表。
2.虚拟地址:共N位,表示:
0-p-1(如4K的页,p为12)表示虚拟页偏移,我们可以通过这个访问4k页的任意地址。
p-n-1: 虚拟页号。
虚拟页和物理页都是P(如4K),这样才能对的上。即PRO == VPO
下图展示页命中时,cpu操作步骤:
1.cpu发出一个虚拟地址,交给MMU
2、MMU生成一个PTE,从高速缓存中请求得到它。
3、高速缓存向MMU返回PTE
4.MMU构造物理地址,并将物理地址传给高速缓存
5.高速缓存返回所请求的数据给处理器。
如果页未命中:
1-3如上:
4.返回的PTE中的有效位是0,MMU触发一次缺页异常。
5.缺页处理程序确认出物理页中的牺牲页,如果此页面已经修改,则回写到磁盘中。
6.缺页处理程序调入新的页面,并更新DRAM中的PTE。
7.CPU会重新发送刚才缺页的VA。此时命中。
9.TLB加速地址翻译
CPU每发出一个VA,MMU就要查阅一次PTE,目的是将虚拟地址翻译成物理地址。为了加快访问速度,引入了TLB(translation lookaside buffer).TLB是一个小的,虚拟地址的缓存(类似于cache),每一行都保存这一个由单个PTE组成的块。