linux 内存管理模块

Posted wenlee

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux 内存管理模块相关的知识,希望对你有一定的参考价值。

什么是MMU

MMU(Memory Management Unit)主要用来管理虚拟存储器、物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权、多任务多进程操作系统。(来自百度百科,对其几个点不熟悉,因此可以只考虑加粗部分

发展历史

注意:学习一个知识点,很重要的一步是了解其为什么而存在?它的存在是为了解决什么问题?然后,在学习的过程中带着这些问题去理解、去思考。

在许多年以前,还是使用DOS或一些古老的操作系统时,内存很小,同时,应用程序也很小,将程序存储在内存中基本能够满足需要。随着科技的发展,图形界面及一些其他更复杂的应用出现,内存已经无法存储这些应用程序了,通常的解决办法是将程序分割成很多个覆盖块,覆盖块0最先运行,运行结束之后,就调用另一个覆盖块,虽然这些操作由OS来完成,但是,需要程序员对程序进行分割,这非常不高效;因此,人们想出了一个虚拟存储器(virtual memory)的方法。虚拟存储器的基本思想是:程序、数据、堆栈的总大小可以超过内存空间的大小,操作系统将当前运行的部分保存在内存中,未使用的部分保存在磁盘中。比如一个16MB的程序和一个内存只有4MB的机器,操作系统通过选择可以决定哪部分4MB的程序内容保存在内存中,并在需要时,在内存与磁盘中交换程序代码,这样16MB的代码就可以运行在4MB的机器中了。注意:这里面包含了虚拟地址和物理地址的概念

相关概念

地址范围、虚拟地址映射成物理地址以及分页机制

  • 地址范围: 指处理器能够产生的地址集合,如一个32bit的处理器ARM9,其能产生的地址集合是0x0000 0000 ~ 0xffff ffff(4G),这个地址范围也称为虚拟地址空间,其中对应的地址为虚拟地址
  • 虚拟地址与物理地址: 与虚拟地址空间和虚拟地址相对应的是物理地址空间和物理地址;物理地址空间只是虚拟地址空间的一个子集。如一台内存为256MB的32bit X86主机,其虚拟地址空间是0 ~ 0xffffffff(4GB),物理地址空间范围是0 ~ 0x0fff ffff(256M)
  • 分页机制
    • 如果处理器没有MMU,或者有MMU但没有启用,CPU执行单元发出的内存地址将直接传到芯片引脚上,被内存芯片(以下称为物理内存,以便与虚拟内存区分)接收,这称为物理地址(Physical Address,以下简称PA),如下图3-1-1所示;

       
      技术图片
      图3-1-1 未使用MMU.png

      如果处理器启用了MMU,CPU执行单元发出的内存地址将被MMU截获,从CPU到MMU的地址称为虚拟地址(Virtual Address,以下简称VA),而MMU将这个地址翻译成另一个地址发到CPU芯片的外部地址引脚上,也就是将VA映射成PA,,如下图3-1-2。
       
      技术图片
      图3-1-2 使用了MMU.png

       

    • 大多数使用MMU的机器都采用分页机制。虚拟地址空间以为单位进行划分,而相应的物理地址空间也被划分,其使用的单位称为页帧,页帧和页必须保持相同,因为内存与外部存储器之间的传输是以页为单位进行传输的。例如,MMU可以通过一个映射项将VA的一页0xb70010000xb7001fff映射到PA的一页0x20000x2fff,如果CPU执行单元要访问虚拟地址0xb7001008,则实际访问到的物理地址是0x2008。

虚拟内存的哪个页面映射到物理内存的哪个页帧是通过页表(Page Table)来描述的,页表保存在物理内存中MMU会查找页表来确定一个VA应该映射到什么PA。

功能

执行过程

操作系统和MMU是这样配合的:

  1. 操作系统在初始化或分配、释放内存时会执行一些指令在物理内存中填写页表,然后用指令设置MMU,告诉MMU页表在物理内存中的什么位置。

  2. 设置好之后,CPU每次执行访问内存的指令都会自动引发MMU做查表和地址转换操作,地址转换操作由硬件自动完成,不需要用指令控制MMU去做。

重要:我们在程序中使用的变量和函数都有各自的地址,在程序被编译后,这些地址就成了指令中的地址,指令中的地址就成了CPU执行单元发出的内存地址,所以在启用MMU的情况下, 程序中使用的地址均是虚拟内存地址,都会引发MMU进行查表和地址转换操作。(注意理解这句话)

内存保护机制

处理器一般有用户模式(User Mode)特权模式(privileged Mode)之分。操作系统可以在页表中设置每个页表访问权限,有些页表不可以访问,有些页表只能在特权模式下访问,有些页表在用户模式和特权模式下都可以访问,同时,访问权限又分为可读可写可执行三种。这样设定之后,当CPU要访问一个VA(Virtual Address)时,MMU会检查CPU当前处于用户模式还是特权模式,访问内存的目的是读数据、写数据还是取指令执行,如果与操作系统设定的权限相符,则允许访问,把VA转换成PA,否则不允许执行,产生异常(Exception)

异常与中断:异常与中断的处理机制类似,不同的是中断由外部设备产生,而 异常由CPU内部产生的;中断产生与CPU当前执行的指令无关,而异常是由于当前执行的指令出现问题导致的

通常操作系统会将虚拟地址空间划分为用户空间内核空间。例如x86平台的linux系统的虚拟地址空间范围是0x0000 0000 ~ 0xffff ffff,前3G的空间为用户空间,后1G的空间为内核空间。用户程序加载到用户空间,内核程序加载到内核空间,用户程序不能访问内核中的数据,也不能跳转到内核空间执行。这样可以保护内核,如果一个进程访问了非法地址,顶多就是这个进程崩溃,而不会影响到内核和系统的稳定性。在系统发生中断或异常时,不仅会跳转到中断或异常服务函数中执行,而且还会从用户模式切换到特权模式,从中断或异常服务程序跳转到内核代码中执行。总结一下:在正常情况下处理器在用户模式执行用户程序,在中断或异常情况下处理器切换到特权模式执行内核程序,处理完中断或异常之后再返回用户模式继续执行用户程序。

段错误我们已经遇到过很多次了,它是这样产生的:

  1. 用户程序要访问的一个VA,经MMU检查无权访问。
  2. MMU产生一个异常,CPU从用户模式切换到特权模式,跳转到内核代码中执行异常服务程序。
  3. 内核把这个异常解释为段错误,把引发异常的进程终止掉。

S3C2440/S3C2410 中的MMU

S3C2440/S3C2410 MMU概述

  1. S3C2440的MMU使用页表来实现虚拟地址到物理地址的转换;页表存储在内存中,页表中的每一行对应于虚拟存储空间的一个页,该行包含了该虚拟内存页对应的物理内存页的地址、该页的方位权限和该页的缓冲特性等。这里页表中的每一行称为一个地址变换条目(entry)也称为“描述符”。描述符有:段描述符、大页描述符、小页描述符、极小页描述符——他们保存段、大页、小页或极小页的起始物理地址;粗页表描述符、细页表描述符——它们保存二级页表的物理地址

  2. 页表的存储:页表存放在内存中,系统通常有一个寄存器来保存页表的基地址。在ARM中系统控制协处理器CP15的寄存器C2用来保存页表的基地址

  3. TLB:因为从虚拟地址到物理地址的变换过程是通过查询页表完成的,而页表又存储在内存中,如果每次程序执行时去读取内存中的数据获取物理地址,代价很大。而程序在执行过程中可能只对页表中的少数几个单元进行访问,根据这一特点,采用一个容量更小(通常为8~16个字)、访问速度和CPU中通用寄存器相当的存储器件来存放当前访问需要的地址变换条目。这个小容量的页表称为TLB(Translation Lookaside buffer)。

  4. S3C2440/S3C2410中的页表
    在S32440/S3C2410中最多会使用两级页表:以段(Section 1MB)的方式进行转换时只用到一级页表,以页(Page)的方式进行转换时用到二级页表。

  5. CPU访问内存的过程
    a . 当CPU需要访问内存时,先在TLB中查询需要的地址变换条目。如果该条目不存在,CPU从位于内存中的页表中查询,并把相应的结果添加到TLB中。这样,当CPU下一次又需要该地址变换条目时,可以从TLB中直接得到,从而使地址变换的速度大大加快。
    b. 当内存中的页表内容改变,或者通过修改系统控制协处理器CP15的寄存器C2使用新的页表时,TLB中的内容需要全部清除。系统控制协处理器CP15的寄存器C8用来控制清除TLB内容的相关操作。
    c. MMU可以将某些地址变换条目锁定在TLB中,从而使得获取该地址变换条目的速度保持很快。在CP15中的C10用于控制TLB内容的锁定。
    d. MMU 可以将整个存储空间分为最多16个域,每个域对应一定的内存区域,该区域具有相同的访问控制属性。MMU中寄存器C3用于控制与域相关的属性的配置
    e. 当存储访问失效时,MMU提供了相应的机制用于处理这种情况。在MMU中寄存器C5和寄存器C6用于支持这些机制

禁止/使能MMU时应注意的问题(重要)

应注意如下几点:

  • 在使能MMU之前,要在内存中建立页表,同时,CP15中的各相关寄存器必须完成初始化
  • 如果使用的不是平板存储模式(物理地址和虚拟地址相等),在禁止/使能MMU时,虚拟地址和物理地址的对应关系会发生改变,这时应该清除cache中的当前地址变换条目

S3C2440/S3C2410中的MMU地址变换

ARM CPU上的地址转换过程涉及3个概念:虚拟地址(VA)、变换后的虚拟地址(MVA, modified virtrual address)、物理地址(PA)。

没启动MMU时,CPU核、cache、MMU、外设等所有部件使用的都是物理地址。

启动MMU后,CPU核对外发出虚拟地址VA;VA被转换为MVA供cache、MMU使用,在这里MVA被转换为PA,最后使用PA读写实际设备。

ARM支持的存储块大小有以下几种:

  • 段(section):是大小为1M的存储块。
  • 大页(Large Pages):是大小为64KB的存储块。
  • 小页(Small Pages):是大小为4KB的存储块。
  • 极小页(Tiny Pages):是大小为1KB的存储块。
    通过配置访问控制机制,还可以将大页分成大小为16KB的子页;将小页分成大小为1KB的子页;极小页不能再细分,只能以1KB大小的整页为单位。

MMU中的域

MMU中的域指的是一些段、大页或者小页的集合。ARM支持最多16个域,每个域的访问控制特性由CP15中的寄存器C3中的两位来控制,CP15中的寄存器C3的格式如下所示:


 
技术图片
C3寄存器.png

其中每两位控制一个域的访问控制特性,其编码及对应的含义如下所示:


 
技术图片
 
MMU内存管理单元介绍

前言

  本篇文章简要阐述MMU的概念,以及以段地址的转换过程为例,简单说明MMU将虚拟地址转换成物理地址的过程。更多详细内容请查看《ARM-MMU(中文手册).pdf》

1、MMU概述

  在ARM存储系统中,使用MMU实现虚拟地址到实际物理地址的映射。为何要实现这种映射?
  首先就要从一个嵌入式系统的基本构成和运行方式着手。系统上电时,处理器的程序指针从0x0(或者是由0Xffff_0000处高端启动)处启动,顺序执行程序,在程序指针(PC)启动地址,属于非易失性存储器空间范围,如ROM、FLASH等。然而与上百兆的嵌入式处理器相比,FLASH、ROM等存储器响应速度慢,已成为提高系统性能的一个瓶颈。而SDRAM具有很高的响应速度,为何不使用SDRAM来执行程序呢?为了提高系统整体速度,可以这样设想,利用FLASH、ROM对系统进行配置,把真正的应用程序下载到SDRAM中运行,这样就可以提高系统的性能。然而这种想法又遇到了另外一个问题,当ARM处理器响应异常事件时,程序指针将要跳转到一个确定的位置,假设发生了IRQ中断,PC将指向0x18(如果为高端启动,则相应指向0vxffff_0018处),而此时0x18处仍为非易失性存储器所占据的位置,则程序的执行还是有一部分要在FLASH或者ROM中来执行的。那么我们可不可以使程序完全都SDRAM中运行那?答案是肯定的,这就引入了MMU,利用MMU,可把SDRAM的地址完全映射到0x0起始的一片连续地址空间,而把原来占据这片空间的FLASH或者ROM映射到其它不相冲突的存储空间位置。例如,FLASH的地址从0x0000_0000-0x00ff_ffff,而SDRAM的地址范围是0x3000_0000-0x31ff_ffff,则可把SDRAM地址映射为0x0000_0000-0x1fff_ffff而FLASH的地址可以映射到0x9000_0000-0x90ff_ffff(此处地址空间为空闲,未被占用)。映射完成后,如果处理器发生异常,假设依然为IRQ中断,PC指针指向0x18处的地址,而这个时候PC实际上是从位于物理地址的0x3000_0018处读取指令。通过MMU的映射,则可实现程序完全运行在SDRAM之中。
  在实际的应用中,可能会把两片不连续的物理地址空间分配给SDRAM。而在操作系统中,习惯于把SDRAM的空间连续起来,方便内存管理,且应用程序申请大块的内存时,操作系统内核也可方便地分配。通过MMU可实现不连续的物理地址空间映射为连续的虚拟地址空间。
  操作系统内核或者一些比较关键的代码,一般是不希望被用户应用程序所访问的。通过MMU可以控制地址空间的访问权限,从而保护这些代码不被破坏。

2、MMU地址映射的实现

  MMU的实现过程,实际上就是一个查表映射的过程。建立页表(translate table)是实现MMU功能不可缺少的一步。页表是位于系统的内存中,页表的每一项对应于一个虚拟地址到物理地址的映射。每一项的长度即是一个字的长度(在ARM中,一个字的长度被定义为4字节)。页表项除完成虚拟地址到物理地址的映射功能之外,还定义了访问权限和缓冲特性等。

2.1 映射存储块的分类 

  MMU 支持基于节或页的存储器访问, MMU 可以用下面四种大小进行映射:
  节 ( Section ) 构成 1MB 的存储器块。
  微页 ( Tiny page ) 构成 1KB 的存储器块。
  小页 ( Small page ) 构成 4KB 的存储器块。
  大页 ( Large page ) 构成 64KB 的存储器块。
  其中对于节映射使用一级转换表就可以了,而对于微页、小页、大页则需要使用两级转换表。

2.2 转换过程 

  要知道虚拟内存机制必须了解ARM9中的3种地址:VA(虚地址),MVA(修正后虚地址),PA(物理地址)
  1)VA,是程序中的逻辑地址,0x00000000~0xFFFFFFFF。
  2)MVA,是修改后的虚拟地址。在ARM9里面,如果VA<32M,利用进程标识号PID转换得到MVA。过程如下:

if(VA < 32M)
     MVA = VA | ( PID<<25 )
else
     MVA = VA

  只是上面的过程是由硬件实现的。这样为VA进行了一级映射,为什么呢?在linux系统里,每个进程的地址空间0-4G,0-3G是进程独有的,称为用户空间,3G-4G是系统的,称为内核空间,所有进程共享。如果两个进程所用的VA有重叠,在切换进程时,为了把重叠的VA映射到不同的PA上,需要重建页表、使无效caches和TLBS。使用了MVA,使进程在VA相同的情况下,使用不同的MVA,进而PA也不同。这就是在VA与PA之间加上一次到MVA的映射的意义。
  3)PA,物理地址,MVA通过MMU转换后的地址。
技术图片
  
  一级页表使用 4096 个描述符来表示 4GB 空间,每个描述符对应 1MB 的虚拟地址,存储它对应的 1MB 物理空间的起始地址,或者存储下一级页表的地址。每个描述符占 4 个字节,格式如下:
技术图片
  
  使用 MVA[31:20]来索引一级页表(20-31 一共 12 位,2^12=4096,所以是4096 个描述符)。其中段地址的转换流程如下图所示:
技术图片
  ①页表基址寄存器位[31:14]和 MVA[31:20]组成一个低两位为 0 的 32 位地址, MMU 利用这个地址找到段描述符。
  ②取出段描述符的位[31:20](段基址,section base address),它和 MVA[19:0]组成一个 32 位的物理地址(这就是 MVA 对应的 PA)

2.3 TLB

  从MVA 到 PA 的转换需要访问多次内存,大大降低了 CPU 的性能,有没有办法改进呢?
  程序执行过程中,用到的指令和数据的地址往往集中在一个很小的范围内,其中的地址、数据经常使用,这是程序访问的局部性。由此,通过使用一个高速、容量相对较小的存储器来存储近期用到的页表条目(段、大页、小页、极小页描述符),避免每次地址转换都到主存中查找,这样就大幅提高性能。这个存储器用来帮助快速地进行地址转换,成为转译查找缓存(Translation Lookaside Buffers, TLB)。
  当 CPU 发出一个虚拟地址时,MMU 首先访问 TLB。如果 TLB 中含有能转换这个虚拟地址的描述符,则直接利用此描述符进行地址转换和权限检查,否则 MMU 访问页表找到描述符后再进行地址转换和权限检查,并将这个描述符填入TLB 中,下次再使用这个虚拟地址时就直接使用 TLB 用的描述符。
  若转换成功,则称为”命中”。Linux 系统中,目前的”命中”率高达 90%以上,使分页机制带来的性能损失降低到了可接收的程度。若在 TLB 中进行查表转换失败,则退缩为一般的地址变换,概率小于 10%。

 

内存管理单元MMU简介

现代操作系统及CPU硬件中,都会提供内存管理单元(memory management unit,MMU)来进行内存的有效管理。内存管理算法有许多,从简单的裸机方法到分页和分段策略。各种算法都有其优缺点,为特定系统选择内存管理算法依赖于很多因素,特别是系统的硬件设计。

1 内存管理的目的

内存管理的目的是为了更好的使用内存(似乎是废话-,-)。 内存是现代操作系统运行的中心。操作系统中任何一个进程的运行都需要内存,但是,操作系统中的内存是有限的;另一方面,从安全的角度出发,进程都需要有自 己的内存空间,其他的进程都不能访问这个私有的空间;同时,内存的分配会导致内存碎片问题,严重影响计算机的性能。以上这三个问题就是一般内存管理算法所 需要处理的目标。

  • 交换
  • 内存保护
  • 碎片问题

2 交换

进程需要在内存中执行,但进程可以暂时从内存中交换(swap)出去到备份存储上,当需要时再调回到内存中去。

 技术图片

 

在基于优先级的交换调度算法中,如果一个更高优先级的进程来了且需要服务,内存管理可以交换出低优先级的进程,以便装入和执行更高优先级的进程。当高优先级的进程执行完毕之后,低优先级的进程可以交换回内存继续执行。这种交换有时被称之为滚出(roll out)、滚进(roll in)。

       通常一个交换出的进程需要交换回它原来的内存空间。这一限制是由地址捆绑方式决定的。如果捆绑是在汇编时或加载时决定的,那么就不可以移动到不同的位置。如果捆绑是在运行时决定,由于物理地址是在运行时才确定,那么进程可以移到不同的地址空间。

交换的代价:交换时间

交换时间主要是指转移时间,总的转移时间和所交换的内存空间成正比。交换不需要或只需要很少的磁头移动,简单的说,交换空间通常作为磁盘的一整块,且独立于文件系统(如Linux的swap空间),因此使用就有可能很快。

交换需要花很多时间,而且进程执行时间却很少,故交换通常不执行,但只有在许多进程运行且内存吃紧时,交换才开始启动。

3 分页

3.1内存保护和内存碎片的背景

内存保护是指操作系统进程不受用户进程的影响,保护用户进程不受其他用户进程的影响。内存保护最基本的思路是进程使用逻辑地址空间,而内存管理单元所看的是物理地址。操作系统将逻辑地址分配给进程,MMU负责逻辑地址到物理地址的映射(转换,捆绑)。

       值得注意的是对于指令(程序)和数据映射到内存地址可以在以下步骤地任意一步执行:

  • 编译时:如果编译时就知道进程将在内存中的驻留地址,那么就可以生成绝对代码。如MS-DOS的COM格式程序。
  • 加载时:如果编译时不知道程序将驻留在何处,那么编译器就必须要生成可重定位代码(relocatable code )。这种情况下,最后地址映射会延迟到加载时才确定,如果开始地址发生变换,必须重新加载程序,以引入新值。
  • 执行时:如果进程在执行时可以从一个内存段移到另一个内存段,那么映射必须延迟到执行时才进程。采用这种方法需要硬件的支持,目前绝大多数操作系统采用这种方法(基于分页、分段等)。

内存碎片是操作系统内存分配的产物。最初操作系统的内存是连续分配的,即进程A需要某一大小的内存空间,如200KB,操作系统就需要找出一块至少200KB的连续内存空间给进程A。随着系统的运行,进程终止时它将释放内存,该内存可以被操作系统分配给输入队列里的其他等待内存资源的进程。

可以想象,随着进程内存的分配和释放,最初的一大块连续内存空间被分成许多小片段,即使总的可用空间足够,但不再连续,因此产生的内存碎片。

一 个办法是不再对内存空间进行连续分配。这样只要有物理内存就可以为进程进行分配。而实际上,不进行连续分配只是相对的,因为完全这样做的代价太大。现实 中,往往定出一个最小的内存单元,内存分配是这最小单元的组合,单元内的地址是连续的,但各个单元不一定连续。这样的内存小单元有页和段。

当然,分段和分页也会产生碎片,但理论上每个碎片的大小不超过内存单元的大小。

3.2 分页

分页时一种内存管理方案,同时也提供了内存保护机制。它允许分配的物理内存地址可以是非连续的。

逻辑内存分为大小相等块的组合,这个块称之为页;物理内存则分为固定大小的帧(frame)。页大小应和帧大小相同,这是由硬件决定的。通常是2的幂,这样可以方便地将逻辑地址映射到物理地址。

基于分页的逻辑地址到物理地址的映射

 技术图片


考虑32位地址。如果页大小是4KB,则需要12位来表示每一页中的某个具体地址,因此32位的逻辑地址中需要12位来对某一页中的具体地址寻址。这12位叫做页偏移。剩下的20位可以作为页码,可以有1M的页。逻辑地址可以表示为:
             技术图片

寻址时,根据页码P查页表,找到该页对应的帧,将帧号与页偏移(也是帧偏移)组合即得到物理地址。这样也说明了为什么页大小要等于帧大小,因为页数要等于帧数。

例如,页大小为4K,页码11对应的帧码是10,即表示是第10块物理帧,也偏移为5,则逻辑地址0X0000b 005对应的物理地址是0X0000a 005。

3.3 分页的内存保护

基于分页的操作系统在分配内存时分给进程所需要的页数,其对应物理内存的帧号同时装入该MMU的页表。同时页表上有一个标记为,指明该页是属于哪个进程的。甚至可以定义该页对于某个进程的读写权限。非法的读写操作会产生硬件陷阱(或内存保护冲突)。

3.4 分页的代价

由上一节可知分页是基于查找表的,而在内存中存储这个1M个项目的页表本身就带来了内存消耗和查找速度问题。于是,页表通常需要硬件的支持,即将页表写在硬件MMU的寄存器中。

如果页表比较小,那么页表写在寄存器中可以加快查找速度。但绝大多数当代的计算机页表都非常大。对于这些页表,采用快速寄存器来实现页表就不太合理了。

一种办法是使用TLB(translation look-aside buffer)。TLB是关联的寄存器,TLB条目由两部分组成:页号和帧号。
技术图片

TLB只包含页表中的一小部分条目,整个页表还是保存在内存中。当CPU产生逻辑地址后,其页号提交给TLB。如果找到了页号,那同时也就找到了帧号,就可以访问物理内存;如果页号不在TLB中(称为TLB失效),那就需要访问页表。在页表中找到帧号后,把页号和帧号增加到TLB中,这样下次再用时可以很快找到。如果TLB中条目已满,则操作系统会根据一个替换策略来替换条目。替换策略有很多,从最近最小使用替换到随机替换等。另外,有的TLB允许某些条目不被替换,如内核代码的条目。

有的TLB还在条目中保存地址空间保护标志符,用来唯一标志进程,以提供进程内存保护。

3.5 页表结构

对于32位以及64位逻辑地址的计算机来说,其页表实在太过庞大。为了压缩页表,一个简单的方法是使用层次化分页算法,就是将页表再分页。(这实际上是一种索引的方法)

技术图片
技术图片

即将2^20个页表项分为2^10个组,每个组里面有2^10项。这样只需要2K*4=8K的页表空间,且查找速度也有很大提升。例如原先最坏情况下要查2^20次,现在最坏只要2*2^10次

 

 

 

内存管理单元MMU(memory management unit) 

 

内存管理单元MMU(memory management unit)的主要功能是虚拟地址(virtual memory addresses)到物理地址(physical addresses)的转换。除此之外,它还可以实现内存保护(memory protection)、缓存控制(cache control)、总线仲裁(bus arbitration)以及存储体切换(bank switching)。


工作机制

技术图片

CPU将要请求的虚拟地址传给MMU,然后MMU先在高速缓存TLB(Translation Lookaside Buffer)查找转换关系,如果找到了相应的物理地址则直接访问;如果找不到则在地址转换表(Translation Table)里查找计算。

虚拟地址

现代的内存管理单元是以页的方式来分区虚拟地址空间(the range of addresses used by the processor)的。页的大小是2的n次方,通常为几KB。所以虚拟地址就被分为了两个部分:virtual page number和offset

技术图片

页表项(page table entry)

上面从虚拟页号在页表里找到的存放物理页表号的条目就是页表项(PTE)。PTE一般占1个字长,里面不仅包含了physical page number,还包含了重写标志位(dirty bit)、访问控制位(accessed bit)、允许读写的进程类型(user/supervisor mode)、是否可以被cached以及映射类型(PTE最后两位)。

映射

  • 映射方式

        映射方式有两种,段映射和页映射。段映射只用到一级页表,页映射用到一级页表和二级页表。
  • 映射粒度

        段映射的映射粒度有两种,1M section和16M supersection;页映射的映射粒度有4K small page、64K large page和过时的1K tiny page。

技术图片

 
 
 
 
 
 

 

以上是关于linux 内存管理模块的主要内容,如果未能解决你的问题,请参考以下文章

Linux 内核 内存管理内存管理架构 ③ ( Linux 内核中的内存管理模块 | 页分配器 | 不连续页分配器 | 内存控制组 | 硬件设备内存管理 | MMU | 页表缓存 | 高速缓存 )

Linux 内核 内存管理内存管理架构 ③ ( Linux 内核中的内存管理模块 | 页分配器 | 不连续页分配器 | 内存控制组 | 硬件设备内存管理 | MMU | 页表缓存 | 高速缓存 )

Linux内核之内存管理完全剖析

linux 内存管理模块

Linux 内核Linux 内核特性 ( 组织形式 | 进程调度 | 内核线程 | 多平台虚拟内存管理 | 虚拟文件系统 | 内核模块机制 | 定制系统调用 | 网络模块架构 )

Linux-0.11内核源代码分析系列:内存管理get_free_page()函数分析