聊一聊Linux虚拟内存技术

2021-03-05    分类: 网站建设

以存储单元为单位来管理显然不现实,因此Linux把虚存

为了使系统可以正确的访问虚存页在对应页框中的映像,在把一个页映射到某个页框上的同时,就必须把页码和存放该页映像的页框码填入一个叫做 页表的表项中。这个页表就是之前提到的映射记录表。一个页表的示意图如下所示:

页模式下,虚拟地址、物理地址转换关系的示意图如下所示:

也就是说:处理器遇到的地址都是虚拟地址。虚拟地址和物理地址都分成页码(页框码)和偏移值两部分。在由虚拟地址转化成物理地址的过程中,偏移值不变。而页码和页框码之间的映射就在一个映射记录表——页表中。

请页与交换

虚存页面到物理页框的映射叫做页面的 加载。

当处理器试图访问一个虚存页面时,首先到页表中去查询该页是否已映射到物理页框中,并记录在页表中。如果在,则MMU会把页码转换成页框码,并加上虚拟地址提供的页内偏移量形成物理地址后去访问物理内存;如果不在,则意味着该虚存页面还没有被载入内存,这时MMU就会通知操作系统:发生了一个页面访问错误(页面错误),接下来系统会启动所谓的“请页”机制,即调用相应的系统操作函数,判断该虚拟地址是否为有效地址。

如果是 有效的地址,就从虚拟内存中将该地址指向的页面读入到内存中的一个空闲页框中,并在页表中添加上相对应的表项,最后处理器将从发生页面错误的地方重新开始运行;如果是 无效的地址,则表明进程在试图访问一个不存在的虚拟地址,此时操作系统将终止此次访问。

当然,也存在这样的情况:在请页成功之后,内存中已没有空闲物理页框了。这是,系统必须启动所谓地 交换机制,即调用相应的内核操作函数,在物理页框中寻找一个当前不再使用或者近期可能不会用到的页面所占据的页框。找到后,就把其中的页移出,以装载新的页面。对移出页面根据两种情况来处理:如果该页未被修改过,则删除它;如果该页曾经被修改过,则系统必须将该页写回辅存。

系统请页的处理过程如下所示:

为了公平地选择将要从系统中抛弃的页面,Linux系统使用 最近最少使用(LRU)页面的衰老算法。这种策略根据系统中每个页面被访问的频率,为物理页框中的页面设置了一个叫做 年龄的属性。页面被访问的次数越多,则页面的年龄最小;相反,则越大。而年龄较大的页面就是待换出页面的好候选者。

快表

在系统每次访问虚存页时,都要在内存的所有页表中寻找该页的页框,这是一个很费时间的工作。但是,人们发现,系统一旦访问了某一个页,那么系统就会在一段时间内稳定地工作在这个页上。所以,为了提高访问页表的速度,系统还配备了一组正好能容纳一个页表的 硬件寄存器,这样当系统再访问虚存时,就首先到这组硬件寄存器中去访问,系统速度就快多了。这组存放当前页表的寄存器叫做 快表。

总之,使用虚拟存储技术时,处理器必须配备一些硬件来承担内存管理的一部分任务。承担内存管理任务的硬件部分叫做存储管理单元MMU。存储管理单元MMU的工作过程如下图所示:

页的共享

在多程序系统中,常常有多个程序需要共享同一段代码或数据的情况。在分页管理的存储器中,这个事情很好办:让多个程序共享同一个页面即可。

具体的方法是:使这些相关程序的

页的保护

由上可知,页表实际上是由

注意:其中的PCD位表示着是否允许高速缓存(cache)。

如果程序对一个页试图进行一个该页控制字段所不允许的操作,则会引起操作系统的一次中断——非法访问中断,并拒绝这种操作,从而保护该页的内容不被破坏。

多级页表

需要注意的是,页表是操作系统创建的用于内存管理的表格。因此,一个程序在运行时,其页表也要存放到内存

当然,如果程序的

为了应用上的灵活,Linux使用一系列的宏来掩盖各种平台的细节。用户可以在配置文件 config中根据自己的需要对页表进行配置,以决定是使用三级页表还是使用二级页表。

在系统编译时,会根据配置文件 config中的配置,把目录 include/asm符号连接到具体CPU专用的文件目录中。例如,对于i386CPU,该目录符号会连接到include/asm-i386,并在文件pgable-2level-defs.h中定义了二级页表的基本结构,如下图:

其中还定义了:

  1. #define PGDIR_SHIFT  22 //PGD在线性地址中的起始地址为bit22 
  2. #define PTRS_PER_PGD  1024  //PGD共有1024个表项 
  3.                       
  4. #define PTRS_PER_PTE  1024  //PTE共有1024个表项 
  5. #endif 

在文件include/asm-i386/pgtable.h中定义了页目录和页表项的数据结构,如下:

  1. typedof struct { unsigned long pte_low; }  pte_t ;                     //页表中的物理地址,页框码 
  2. typedof struct { unsigned long pgd; }  pgd_t ;                         //指向一个页表 
  3. typedof struct { unsigned long pgprot; }  pgprot_t ;                   //页表中的各个状态信息和访问权限 

从定义可知,它们都是只有一个 长整型类型(32位)的结构体。

注意:如上文的“页的保护”部分,页框码代表物理地址,只需要高20位就够了(因为页框的长度为4KB,因此页内偏移12位)。而后12位可以存放各个状态信息和访问权限。但是Linux并没有这样做,反而重新定义了一个结构体来存放,通过“或”运算来将两者结合。

文章标题:聊一聊Linux虚拟内存技术
URL网址:https://www.cdcxhl.com/news/104401.html

成都网站建设公司_创新互联,为您提供微信小程序动态网站定制开发微信公众号网站设计做网站

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

微信小程序开发