MMU探索之旅

现在有很多关于MMU的讲解材料,大都比较晦涩难懂,参考了一些相关材料后,在这里用简明易懂的语言整理一下,以备后用。

       在讲解MMU之前,先看看我们需要对MMU了解哪些方面:

     (1)MMU的产生

     (2)MMU的概述

     (3)MMU的功能和原理

     (4)MMU使用的相关软硬件支持

    这里只是对MMU做一个较为概括的讲述,内部的具体实现得参考相关书籍。

(1)MMU的产生

    大家都知道,以前的计算机的内存都很小,基本上都是KB级别的,之所以在这么小的内存中跑程序,是因为以前的应用程序都是文本界面的,程序本身也比较小。但是,后来程序日趋图形化,而且应用软件也被做的越来越多大,小内存的瓶颈越显突出,虽然曾有过一些办法来缓解这种局面,但是这根本解决不了问题,而且费时费力。

    不久人们找到了一个办法,这就是虚拟存储器(virtual memory)技术,虚拟存储器的基本思想是程序,数据,堆栈的总的大小可以超过物理存储器(物理内存)的大小,操作系统把当前使用的部分保留在内存中,而把其他未被使用的部分保存在磁盘上,这样对于用户而言,真的好像在很大的内存中跑程序一样。

(2)MMU的概述

    在介绍MMU概念之前,先来了解一下地址范围,虚拟空间,虚拟地址,物理空间,物理地址,分页机制等概念。

    地址范围:计算机上的一个程序(或者说处理器)能够产生的地址集合,我们称之为地址范围。这个范围的大小随着计算机的体系结构的不同而不同,即由CPU的位数决定,例如一个32位的CPU,它的地址范围是0~0xFFFFFFFF (4G),这是目前pc机上最常用的地址范围。而对于一个64位的CPU,它的地址范围为0~0xFFFFFFFFFFFFFFFF (64T).这个范围就是我们的程序能够产生的地址范围,本质上,地址范围是由系统地址总线的数量决定的,即如果你的机器上有n根地址总线,就有2的n次方的地址范围。

    虚拟空间和虚拟地址:我们把地址范围称为虚拟地址空间,该空间中的某一个地址我们称之为虚拟地址。

    物理空间和物理地址:与虚拟地址空间和虚拟地址相对应的则是物理地址空间和物理地址,大多数时候我们的系统所具备的物理地址空间只是虚拟地址空间的一个子集。这里举一个最简单的例子直观地说明这两者,对于一台内存为256M的32bit x86主机来说,它的虚拟地址空间范围是0~0xFFFFFFFF(4G),而物理地址空间范围是0x000000000~0x0FFFFFFF(256M)。

    分页机制:大多数使用虚拟存储器的系统都使用一种称为分页(paging)机制,在不同的机器上页的大小不同,一般是4KB,(在后面的叙述中的页也是指4KB),虚拟地址空间划分成称为页(page)的单位,而相应的物理地址空间也被进行划分,单位是页桢(frame)页和页桢的大小必须相同,这样就可以把物理空间和虚拟空间进行准确的映射了,这在后面会详细介绍。

        MMU:在没有使用虚拟存储器的机器上,虚拟地址被直接送到内存总线上,使具有相同地址的物理存储器被读写;而在使用了虚拟存储器的情况下,虚拟地址不是被直接送到内存地址总线上,而是送到存储器管理单元MMU,把虚拟地址映射为物理地址,然后将映射后的物理地址送到内存的地址总线上。

 

(3)MMU的功能和原理

    因为我是学ARM的,所以在这里以ARM系统为例,MMU主要完成以下工作:

       <1> 虚拟存储空间到物理存储空间的映射,实现从虚拟地址到物理地址的转换

       <2> 存储器访问权限的控制

       <3> 设置虚拟存储空间的缓冲特性

       老规矩,在介绍MMU的功能和原理之前,先来了解一下几个名词:

       1 传输表:这是一种页表,用来保存虚拟地址到物理地址的映射信息。既然是页表,就是说这里有4K(4096)个表项,每个表项占4个字节,所以传输表的大小为16KB。

       2 TLB:Translation Lookaside Buffer,这是一个小容量的Cache,称为块表,是用来提高虚拟地址到物理地址映射的速度的,后面会详细介绍。

       3 CP15:ARM总共有16个协处理器,这是最后一个协处理器,也是最总要的一个(个人看法,因为系统底层的程序员总要跟它打交道),用来协调ARM处理器工作的,相信你能从名字上看得出来。

       4 c0, c1, ……, c15:这些寄存器每个协处理器都有,名字一样但对应的物理寄存器却不同,用来控制协调协处理器工作的,包括对MMU操作的影响。

       5 MPU:这是内存保护单元,不用多说,是用来保护内存不被非法破坏的,它和MMU相得益彰,这里不对MPU多做解释。

 

<1> 虚拟存储空间到物理存储空间的映射

       这里从处理器访问内存过程来说明MMU的工作原理,为了便于理解我们由简入深讲解,然后总结访问内存的详细流程:

       当处理器产生一个内存访问请求时,将传输一个虚拟地址给MMU(如果机器没有MMU功能或禁止了MMU功能就另当别论),那么它会转入保存在内存中的传输主表(在下面我将用段表来代替),来获取所有访问地址的物理地址和访问权限,这里假设虚拟内存映射采用二级映射,先以图示之:

 

 

 

 

 

    如上图所示,C2是CP15协处理器的一个寄存器,里面存放的是段表的首地址。

    虚拟地址被分为三部分,第一部分且称为段表偏移,用来指示访问内存的地址在段表中的偏移,这里的段偏移之所以是12位,是因为段表共有4096(12位才能表示)个段表项,每个段有4MB的空间;第二部分用来指示访问内存的地址在虚拟页表中的偏移,每个页表项能代表4KB的空间,;第三部分是要访问的内存地址相对于确定后的物理页首地址的偏移量。

注意:段表和虚拟页表都是存储在内存中的。

    现假设处理器传送的虚拟地址为0X00101002,转换成二进制为00000000 00010000 00010000 00000010,可以容易算出段偏移为1,页表偏移为4,页偏移2。MMU的处理过程如下:首先根据CP15协处理器的C2寄存器确定段表的首地址,假设这里的段表的基地址是0x30000000,然后通过段偏移1确定要访问的内存地址在段表中的偏移地址0x30000004,每个段表项中存有虚拟页表的首地址,由该地址找到虚拟页表的首地址,假设为0x31000000,再根据页表偏移确定一个虚拟页0x31000010,而这个页中就存有要访问的内存地址的物理页的首地址,然后再由页偏移找到要访问的时间内存地址,最后再把存在该地址中的数据通过系统总线传给处理器。

    很明显,处理器访问一次内存在上述的执行过程中,共需要访问内存三次,这样的效率非常的低下。如果要减少访存的次数,可以将虚拟地址到物理地址的二次映射换为一次映射,即把段表和页表合二为一,有很多的机器就是采用了这种转换方式,可这样又会造成另一个问题,如果采用一级映射,那么映射相同大小4G内存空间一定需要4MB的段表空间,采用二级映射映射4G的内存空间完全映射需要4MB+4KB,表面上二级映射需要的空间更大,在加上比一级映射多一次访存,好像二级映射完全失去优势,但我们应该理论实践相结合,在实际的程序执行中,每一个应用进程都有自己操作的地址空间,这个空间的基本分配方式如下图所示:

 

 

 

 

    在用户空间内,堆的空间占绝大部分,而堆在使用中存在很大的空洞,不被使用,而栈一般只有一到两页,所以在程序的实际运行中,用户空间基本上都只使用前后的几个页,所以在二级映射中可以只映射其中的几个页,而在一级映射中必须映射所有的页,这样,二级映射中的多一次访存的代价就微不足道了。

    那么,如何提高MMU的映射效率呢,这就是TLB---快表。

       TLB其实就是一个小容量的cache,一般大小在4lines~64lines,每行4字节即16bytes~256bytes,每一行存放的是最近使用的映射记录,使一种全相联的映射方式。当处理器再次访问TLB中存有的虚拟地址映射到物理地址的映射记录时,就可以直接从对应的物理内存中提取想要的数据,这样,处理器访存只需要一次访存就能得到数据,又因为程序访问具有局部性,所以TLB还是能很大的提高访存效率的。在有TLB的MMU中,上述的过程中处理器发出的虚拟地址会首先和TLB检测匹配,如果没有匹配项才去访问内存中的主传输表,在读取内存的数据后MMU会将这次的映射记录放进TLB,如果TLB被存满,则会采用一种叫RLU算法,替换掉最近最少使用的映射记录。

    那么,在这里还用一个值得注意的地方,在ARM和内存之间还有一个硬件设备,就是cache。虽然我们主要介绍的是MMU,但cache缓存技术在处理器访存中起到至关重要的作用,它可以极大提高访问内存的效率,很多处理器系统芯片上集成了多级的cache,这里就简单介绍一下cache在MMU管理之余所扮演的角色。在处理器发送出虚拟地址后,首先与cache中各项进行匹配,如果命中cache则直接从cache中读取数据,而不用使用MMU,至于如何匹配cache项,视具体cache结构而定,这里也不做详细解释,可以查看相关材料。如果没有命中cache,则通过MMU将虚拟地址映射到物理地址,到内存中相应的物理地址处读取数据,然后将该数据所在的一整块数据读入cache中,如果cache已满,则采用预定的替换策略替换掉相应的块。同样,由于程序的执行具有局部性,所以cache对访存效率的提高是显著的。

 

<2> 存储器访问权限的控制

       当应用程序的所有线程共享同一存储器空间时,任何一个线程将有意或无意地破坏其它线程的代码、数据或堆栈。异常线程甚至可能破坏内核代码或内部数据结构。例如线程中的指针错误就能轻易使整个系统崩溃,或至少导致系统工作异常。 

     就安全性和可靠性而言,基于进程的实时操作系统(RTOS)的性能更为优越。为生成具有单独地址空间的进程,RTOS只需要生成一些基于RAM的数据结构并使MMU加强对这些数据结构的保护。基本思路是在每个关联转换中“接入”一组新的逻辑地址。MMU利用当前映射,将在指令调用或数据读写过程中使用的逻辑地址映射为存储器物理地址。

    简单说访问控制机制就是CPU通过目中方法判断当前程序对内存访问是否合法(是否有权对内存进行访问),如果当前的程序没有权限访问内存,则CPU将引发一个异常,S3c2440成为Permission fault,例如user级别的程序要对一个system级别的内存区域进行些操作。那么S3c2440的访问控制机制到底是由什么参与完成的呢?有下面的几个寄存器的踊跃参与,才使其正常工作:

      1 协处理器CP15中的C3:域访问控制寄存器(domain accesss control register)

      2 段描述符中的AP位和domain位

      3 协处理器CP15中C1中的S bit和R bit

      4 协处理器CP15中C5,C6

控制访问:

       域访问控制寄存器是访问控制寄存器,有32个有效位,被分为16个区域,每个区域由两位组成,有四种组合如下:

       00:该级别下,内存区域不允许被访问,任何访问都会产生domain fault

       01:该级别下,该内存的访问必须配合该内存的段描述符中的AP位进行权检查

       10:保留

       11:该级别下:对内存区域的访问都不进行权限检查

注意:

       1 对某个内存区域的访问是否需要进行权限检查是由该内存区域的描述符中的domain域决定的。

       2 某个内存区域的访问权限是由该内存区域的描述符中的AP位和协处理器CP15中控制寄存器中的S bit和R bit所决定。

 

<3> 设置虚拟存储空间的缓冲特性

       这是对cache缓存的是否可用进行的控制。

      

    讲解道这里,就基本讲完,现在我们来对内存的访问过程进行总结:

       1 当处理器产生一个内存访问请求时,将传输的虚拟地址首先传给cache(根据入口中的C(cachable)控制位和B(bufferable)控制位决定是否允许缓存的存储访问,如果不允许缓存,则不对cache进行下面的一切操作),对cache进行匹配,这是由cache的控制器控制完成的,如果命中cache,则将cache中虚拟地址对应的数据取出发送到数据总线上,传给cpu。

      2 如果没有命中cache,则将虚拟地址传输给MMU(如果机器没有MMU功能或禁止了MMU功能就另当别论),MMU首先遍历TLB快表,有的系统采用哈佛结构(指令cache和数据cache分开存储)需要分别遍历指令TLB和数据TLB,如果命中TLB,则从TLB中取出映射的物理地址,并根据虚拟地址中的页偏移读取内存中对应地址中的数据,并把其送到数据总线上,传给cpu,并将内存中该数据所在的一整块的数据通过cache内容获取硬件读到cache中,如果cache已满,则采用预定的替换策略替换掉相应的块。

   3 如果没有命中TLB,则MMU通过页表遍历硬件通过前面叙述的二级映射机制找到物理地址,在读取内存的数据后MMU会将这次的映射记录放进TLB,如果TLB被存满,则会采用一种叫RLU算法,替换掉最近最少使用的映射记录,并将内存中该数据所在的一整块的数据通过cache内容获取硬件读到cache中,如果cache已满,则采用预定的替换策略替换掉相应的块。

 

   上面所说的内容没有包括访问权限的控制,在这里补充一下:

   只有在TLB的匹配时才进行访问权限的检查,根据检查域访问控制位和访问权限控制位的结构判断,如果出现任一种不合法情况,则本次访问就会产生访问异常,并终止本次访问。现在以图示访存的过程:

 

 

                                                              图3

 

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值