1. MMU

MMU在CPU的配合下(通过页异常触发),实现了线性地址到物理地址的动态映射,为正在CPU上运行的应用程序(进程)提供了一个独立的连续内存空间(线性地址空间,或称虚拟内存空间,其中放置了代码段、数据段和堆栈段),屏蔽了地址分配、内存分配和内存回收等一系列复杂的系统行为。

MMU的线性地址转换是通过页表进行的,具体过程如下图所示(摘自intel程序员手册卷3):

其实最简单明了的方法是通过一个一维数组来记录映射关系:下标代表线性地址,数组元素内容代表物理地址。可是如此一来,用来表示映射关系的内存空间比被表示的物理空间还要大,显然这不是一个可行的方案。

工程师们采用了分段分级的思路来表示这种映射关系:先把线性空间以4K大小为单位进行划分(页),然后再以大段连续空间进行转换,在每个大段空间内部再次划分成小段进行转换,直到段大小变为4K页大小。用以表示和段空间映射关系的结构称为页表,其大小也是一个页面。由于采用了分段的方法,页表空间大大减小;同时未映射的空间不必分配页表,这也进一步降低了页表占用空间。

x86_64架构下Linux用了四级页表来表示一个映射关系,依次为PGD、PUD、PMD、PT。每级页表4K大小,内部元素大小为8字节,高位指向了下一级页表的物理地址,低位表示页表属性(是否存在、读写权限、是否脏等等)。顶层页表PGD的物理地址存放在CPU的CR3寄存器中,供MMU访问。48位线性地址也相应地分成了五段:前四段,每段长9位,用来索引对应页表的元素;最后一段长12位,用来在页面中索引物理地址。各级页表的详细内容参考下表:
  

2. 页表转换过程

Linux系统中每个进程对应用户空间的pgd是不一样的,但是linux内核 的pgd是一样的。当创建一个新的进程时,都要为新进程创建一个新的页面目录PGD,并从内核的页面目录swapper_pg_dir中复制内核区间页面目录项至新建进程页面目录PGD的相应位置,具体过程如下:
do_fork() --> copy_mm() --> mm_init() --> pgd_alloc() --> set_pgd_fast() --> get_pgd_slow() --> memcpy(&PGD + USER_PTRS_PER_PGD, swapper_pg_dir +USER_PTRS_PER_PGD, (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t))

这样一来,每个进程的页面目录就分成了两部分,第一部分为“用户空间”,用来映射其整个进程空间(0x0000 0000-0xBFFF FFFF)即3G字节的虚拟地址;第二部分为“系统空间”,用来映射(0xC000 0000-0xFFFF FFFF)1G字节的虚拟地址。可以看出Linux系统中每个进程的页面目录的第二部分是相同的,所以从进程的角度来看,每个进程有4G字节的虚拟空间,较低的3G字节是自己的用户空间,最高的1G字节则为与所有进程以及内核共享的系统空间。每个进程有它自己的PGD( Page Global Directory),它是一个物理页,并包含一个pgd_t数组。

  • PTE: 页表项(page table entry)
  • PGD(Page Global Directory)
  • PUD(Page Upper Directory)
  • PMD(Page Middle Directory)
  • PT(Page Table)

PGD中包含若干PUD的地址,PUD中包含若干PMD的地址,PMD中又包含若干PT的地址。每一个页表项指向一个页框,页框就是真正的物理内存页。

3. TLB

Translation lookaside buffer,即旁路转换缓冲,或称为页表缓冲;里面存放的是一些页表文件(虚拟地址到物理地址的转换表)。又称为快表技术。如果匹配到逻辑地址就可以迅速找到页框号(页框号可以理解为页表项),通过页框号与逻辑地址的后12位的偏移自合得到最终的物理地址。如果没在TLB中匹配到逻辑地址,就出现TLB不命中(TLB Misss),需要通过常规的页表查询。如果TLB足够大,那么这个转换就会变得迅速。但是事实是TLB的容量非常小,一般都是几十项到几百项不等。

在有些的处理器架构中,为了提供效率,还将TLB进行分组,以X86架构为例,一般都分为以下四个组:

   第一组:缓存一般页表(4KB页面)的指令页表缓存(Instruction-TLB)第二组:缓存一般页表(4KB页面)的数据页表缓存(Data-TLB)第三组:缓存大尺寸页表(2MB/4M页B面)的指令页表缓存(Instruction-TLB)    第四组:缓存大尺寸页表(2MB/4MB页面)的数据页表缓存(Data-TLB)

举一个例子:假设一个应用程序需要使用8KB的物理内存,如果使用常规页(4KB)并且使TLB总能命中,那么至少需要在TLB表中存放两个表项,在这种情况下,只要寻址的内容都在该内容页内,那么只要两个表项就足够了。如果该应用程序需要使用512个内容页也就是2MB大小,那么需要512个页表表项才能保证不会出现TLB不命中的情况。但是TLB容量有限,随着程序的变大或者使用内存的增加,那么势必会增加TLB的使用项,最后导致TLB出现不命中的情况。此时,大页的优势就显示出来了,如果使用2MB作为分页的基本单位,那么只需要一个页表项就可以保证不出现TLB不命中的情况;对于消耗内存以GB(2^30)为单位的大型程序,可以采用1GB为单位作为分页的基本单位,减少TLB不命中的情况。

参考:
https://rootw.github.io/2017/08/%E5%9C%B0%E5%9D%80%E6%98%A0%E5%B0%84/
https://blog.csdn.net/wangquan1992/article/details/105047639/

内存管理单元MMU简介相关推荐

  1. 操作系统 内存管理单元MMU TLB

    前言 在了解操作系统 内存管理 分页/分段/段页式管理.操作系统 虚拟内存技术两篇文章后,接下来继续看看现代操作系统基本内存管理方式,本文详细介绍Linux操作系统下的内存管理单元MMU和TLB. d ...

  2. ARM920T内存管理单元MMU

    作为程序员已经有4-5个年头了,发现学的知识杂且乱,很多学习过的东西,有时也会忘记.索性开始整理,由于是电子专业出身,于是想把之前玩过的2440开发板,重新再玩一遍.顺便对各个知识点进行较全面的总结. ...

  3. 内存管理单元--MMU

    现代操作系统普遍采用虚拟内存管理(Virtual Memory Management)机制,这需要处理器中的MMU(Memory Management Unit,内存管理单元)提供支持,本节简要介绍M ...

  4. 内存管理单元MMU学习

    MMU MMU是Memory Management Unit的缩写,中文名是内存管理单元,有时称作分页内存管理单元(英语:paged memory management unit,缩写为PMMU). ...

  5. Linux 中的内存管理单元MMU

    MMU (内存管理单元) 基础概念 1.TLB – 转换旁路缓存,里面存放着少量的虚拟内存与实际物理内存之间的对应关系,被称为快表. 2.TTW – 漫游转换表,当TLB中没有对应的转换关系,通过对内 ...

  6. 内存管理单元MMU - ARM内核扩展(一)

    了解物理地址和虚拟地址的关系 掌握如何通过设置MMU来控制虚拟地址到物理地址的转化 了解MMU的内存访问权限机制 了解TLB.Cache.Writebuffer的原理,使用时的注意事项 在计算机开始阶 ...

  7. 内存管理单元——MMU

    一.基本概念介绍 MMU是Memory Management Unit的缩写,中文名是内存管理单元,有时称作分页内存管理单元(英语:paged memory management unit,缩写为PM ...

  8. 【软件开发底层知识修炼】三 深入浅出处理器之三 内存管理与内存管理单元(MMU)

    学习交流加 个人qq: 1126137994 个人微信: liu1126137994 学习交流资源分享qq群: 962535112 上一篇文章学习了中断的概念与意义,以及中断的应用-断点调试原理.点击 ...

  9. MMU内存管理单元简介

    MMU 全称叫做 Memory Manage Unit,也就是内存管理单元. 在老版本的 Linux 中要求处理器必须有 MMU,但是现在 Linux 内核已经支持无 MMU 的处理器了. MMU 主 ...

最新文章

  1. 中文论文万能句型_SCI 论文写作万能句型(每天一点小进步哦)
  2. 使用EventViewer记录VSTO add-in启动错误
  3. JavaWeb学习总结(二):Tomcat服务器学习和使用(一)
  4. 授人以鱼不如授人以渔——CPU漏洞的Symantec解决之道
  5. 程序员与「中台」的爱恨交错
  6. !+\v1 用来“判断浏览器类型”还是用来“IE判断版本”的问题!
  7. 【操作系统】页置换算法
  8. HDU4027 (线段树/修改区间,询问区间和)
  9. hikari如何切换数据源_spring boot+mybatis 多数据源切换(实例讲解)
  10. 378.有序矩阵中第k小的元素(力扣leetcode) 博主可答疑该问题
  11. java统计汉字个数_java统计汉字字数的方法示例
  12. JAVA刷视频代码,Java+adb命令实现自动刷视频脚本
  13. Mysql索引失效的几种情况总结
  14. c#制作图表(从数据库读取数据,制作柱状图,扇形图)
  15. 图解蓝牙 BR/EDR 和BLE的区别
  16. python 字符串删除首尾空格
  17. 云原生相关介绍,什么是云原生很全面
  18. 中国微粉化蜡行业市场供需与战略研究报告
  19. 米公益完结项目结项反馈——“多彩世界,快乐3D”
  20. disk2vhd系统转换成虚拟镜像工具

热门文章

  1. mysql 几种插入数据的方法
  2. 《数学建模:基于R》——1.1 数据的描述性分析
  3. nginx+Tomcat实现动静分离架构
  4. LVM逻辑卷管理基本概念及原理
  5. node.js调用ejs模板,在浏览器上打印出ejs模板内代码的解决方案
  6. 500 OOPS: vsftpd: refusing to run with writable root inside chroot()
  7. 为CheckBoxList每个项目添加一张图片
  8. pgpool-II 高可用搭建
  9. 硬核 | 亚洲诚信@FreeBuf企业安全俱乐部,实力诠释“S/MIME可信企业安全邮件解决方案”...
  10. 阿里巴巴合伙人闻佳:创新背后的文化与组织