MMU和TLB详解

MMU和TLB

MMU

虚拟存储器的基本思想是程序,数据,堆栈的总的大小可以超过物理存储器的大小,操作系统把当前使用的部分保留在内存中,而把其他未被使用的部分保存在磁盘上。

  • 比如对一个16MB的程序和一个内存只有4MB的机器,OS通过选择,可以决定各个时刻将哪4M的内容保留在内存中,并在需要时在内存和磁盘间交换程序片段,这样就可以把这个16M的程序运行在一个只具有4M内存机器上了。
  • 而这个16M的程序在运行前不必由程序员进行分割。
  • 一个物理存储块(通常为一个页框)被多个逻辑页映射。

伴随着这种技术的出现,“virtual address,即VA”和“physical address, 即PA”也就出现了。一般来说,CPU看到的地址是VA,VA是有地址线来决定的。

  • 比如,s3c2410是32位的SoC,那么它的寻址空间为 2^32=4GB,那么VA空间也就是4GB。

既然PA没有VA那么大,而且CPU只能看到 VA,那么CPU如何找到PA呢?**这也正是MMU的基本作用之一,就是提供VA到PA的转换机制,除了硬件的支持外,软件上实际就是维护一张表,表中的内 容是VA到PA的转换法则。**由于有了MMU,那么就可以实现利用VA找到实际物理内存区域。具体的转换方法将在以后介绍。

总而言之,CPU认为的内存空间是由其地址线决定的,但是我们真实的内存空间可能会发生与认为的不匹配,所以我们就引入了虚拟内存,虚拟内存就需要MMU来进行映射。

什么是MMU

MMU是 Memory Management Unit 的缩写即,内存管理单元. 针对各种CPU, MMU是个可选的配件. MMU负责的是虚拟地址与物理地址的转换. 提供硬件机制的内存访问授权.(现代 CPU 的应用中,基本上都选择了使用 MMU)

现代的多用户多进程操作系统, 需要MMU, 才能达到每个用户进程都拥有自己的独立的地址空间的目标. 使用MMU, OS划分出一段地址区域,在这块地址区域中, 每个进程看到的内容都不一定一样.

例如MICROSOFT WINDOWS操作系统, 地址4M-2G处划分为用户地址空间. 进程A在地址 0X400000映射了可执行文件. 进程B同样在地址 0X400000映射了可执行文件. 如果A进程读地址0X400000, 读到的是A的可执行文件映射到RAM的内容. 而进程B读取地址0X400000时则读到的是B的可执行文件映射到RAM的内容.

MMU 作用

MMU 的作用:

  1. 将虚拟地址翻译成为物理地址,然后访问实际的物理地址
  2. 访问权限控制

MMU 工作过程

参考了这篇

一些概念

  • MMU 进行虚拟地址转换成为物理地址的过程是 MMU 工作的核心
  • 大多数使用虚拟存储器的系统都使用一种称为分页(paging)
  • 虚拟地址空间划分成称为**页(page)**的单位;
  • 而相应的物理地址空间也被进行划分,单位是页框-也可以说是块(frame),这里的块就是计组里面的内存划分块了。
  • 页和页框的大小必须相同。

工作过程

我们已经知道,大多数使用虚拟存储器的系统都使用一种称为分页(paging)的技术。

虚拟地址空间被分成大小相同的一组页,每个页有一个用来标示它的页号(这个页号一般是它在该组中的索引,这点和C/C++中的数组相似)。

分配页号:我们可以假设04K的页号为0,48K的页号为1,8~12K的页号为2,以此类推。

而虚拟地址(注意:是一个确定的地址,不是一个空间)被MMU分为2个部分

  • 第一部分是页号索引(page Index)
  • 第二部分则是相对该页首地址的偏移量(offset)

使用虚拟地址中的虚页号查询页表得到对应的物理页号,然后与虚拟地址中的页内位移组成物理地址。

内存保护

MMU除了具有地址翻译的功能外,还提供了内存保护功能。

采用页式内存管理时可以提供页粒度级别的保护,允许对单一内存页设置某一类用户的读、写、执行权限.

比如:一个页中存储代码,并且该代码不允许在用户模式下执行,那么可以设置该页的保护属性,这样当处理器在用户模式下要求执行该页的代码时,MMU会检测到并触发异常,从而实现对代码的保护。

TLB

参考

页表以数据结构的方式存放在DDR(DDR是一个内存名称,意思即双倍速率同步动态随机存储器,是内存的其中一种)中,假如cpu每做一次地址访问,都要去DDR里去取出1级描述符,然后解析1级描述符,再去查找2级描述符,解析2级描述符,加上偏移得到物理地址,那真是太慢了。

MMU的cache-TLB

TLB的全称是Translation Lookaside Buffer,我们知道,处理器在取指或者执行访问memory指令的时候都需要进行地址翻译,即把虚拟地址翻译成物理地址。而地址翻译是一个漫长的过程,需要遍历几个level的Translation table,从而产生严重的开销。为了提高性能,我们会在MMU中增加一个TLB的单元,把地址翻译关系保存在这个高速缓存中,从而省略了对内存中页表的访问

TLB也是一种cache,有cache也就意味着数据有多个copy,因此存在一致性(coherence)问题。和数据、指令cache或者unified cache不同的是,硬件并不维护TLB的coherence,一旦软件修改了page table,那么软件也需要进行TLB invalidate操作,从而维护了TLB一致性。

快速上下文切换FSCE

对于MMU如何识别进程的切换,几乎所有的参考资料上(包括ARM体系结构)均讲解的是快速上下文切换的方法,但其实操作系统并没有使用

**快速上下文切换扩展FCSE(Fast Context Switch Extension),是MMU中的一个附加硬件,用于提高ARM嵌入式系统的系统性能。FCSE使得多个独立的任务可以运行在一个固定的重叠存储空间中,而上下文切换时又不需要清理或清除cache,或TLB。**如果没有FCSE,则从一个任务切换到另一个任务需要改变虚拟存储映射。

如果涉及两个有重叠地址的任务,则保存在cache和TLB中的信息将变为无效,这样系统就必须清除cache和TLB中的无效数据。清除这些模块的过程使任务切换增加了很多时间,因为内核不仅要清除cache和TLB中的无效数据,还要从主存中装载新的数据到cache和TLB。

使用FCSE,虚拟存储管理增加了一次地址转换。FCSE在虚拟地址到达cache和TLB前,使用一个特殊的,包含进程ID值的重定位寄存器来修改虚拟地址。把修改之前的虚存地址称为VA(Virtual Address),把第一次转换之后的地址称为修改后虚地址MVA(Modified Virtual Address)

这样,任务间的切换就不用涉及到改变页表,只需简单的将新任务的进程ID写到位于CP15的FCSE进程ID寄存器。为了利用FCSE,编译链接所有的任务,使他们都运行在虚存的第一个32MB块空间,为每个任务分配一个进程ID;然后通过下边的公式,将每个任务放置在修改后虚存的不同32MB分区中:MVA = VA +(0x2000000 * 进程ID)

FSCE的一个主要限制是您最多有128个进程,并且每个进程的大小被限制为2^25或32MB才能利用它。它还消耗大量的虚拟地址空间。这就是为什么它从未被引入Linux主线的原因。尽管许多嵌入式Linux设备可能受益,但它不像ASID那样通用,ASID支持256个进程,没有大小限制,也不消耗虚拟地址空间。

Global TLB和non-global

现代OS都将地址空间分为内核空间和用户空间。内核空间特权态访问,用户空间用户态访问。

内核空间内容基本各个进程(包括内核线程)都差不多,内核地址空间是一样的,因此对于这部分地址翻译,无论进程如何切换,内核地址空间转换到物理地址的关系是永远不变的,在进程的时候,不需要清掉。

对于用户空间,各个进程的内容都不太一样,保留只会造成混乱,需要清掉。在这种思路引导下,**CPU在切换进程的时候,只会清掉不带Global标志的用户空间页表TLB,而不会动带有global标志的内核页表项。**一个新的进程会开始一个半新的TLB,效能提高不少。

TLB失效

TLB的原理就是将映射到物理页框的虚拟页面的映射关系缓存在MMU中的硬件缓冲当中,每次MMU拿到一个虚拟地址后,都根据地址分析出虚拟页面号,然后查找TLB中有没有该页面的项目,有的话则取出其中的物理页框号,加上页内地址获得实际的物理地址送到地址总线上去访问内存,没有该页面的项目的话,即TLB失效的情况下,有两种方式去处理:

1.硬件处理TLB失效

即发生虚拟页号在TLB中找不到的情况,有两个原因:

  1. 该页面没有被加载到内存:这种情况就是缺页错误,MMU到进程的页表上查找发现页面没有在内存中,需要引发缺页中断,然后调用操作系统的一个汇编函数,由操作系统根据寄存器中的地址或者最后一条运行的指令拿到发生缺页错误的虚拟地址,根据虚拟页面号从磁盘中将页面加载到内存(当中可能涉及页面交换,由于内存空余页面不足,需要将内存中不常访问使用的页面换出到磁盘上的交换空间),然后更新发生缺页的进程的页表,将该虚拟页号和物理页框号的映射写到页表中,接着返回到CPU上再次执行最后一条指令,此时TLB上仍然没有该虚拟页面的表项,因此,由MMU到进程的页表中查找,找到该页面号的映射关系,取出该映射关系,加入到TLB中(如果TLB的表项中没有空余的空间,则牺牲一条已有表项)中,最后取出表项中的物理页框号,组成物理地址访问物理内存。
  2. 页面已被加载到内存,只是TLB中没有对应的映射关系:这种情况大部分是由于该页面的映射关系在TLB之前新增表项的时候被牺牲了,因此只要MMU在去进程的页面中重新加载该映射关系既可。

2.软件处理TLB失效

软件处理TLB失效和硬件处理方式雷同,最大的区别在于查找进程页表中的虚拟页面的映射关系以及添加映射关系到TLB表的操作由操作系统来完成。

你可能感兴趣的:(系统架构,硬件架构,嵌入式硬件)