蓝盟云服务,谈谈Linux虚拟内存技术

发布者:上海IT外包 来源:www.linemore.com

     以存储单元为单位进行管理显然是不现实的,因此Linux将虚拟存储空间划分为几个大小相等的存储分区。 Linux将这样的分区称为页面。为了便于交换和交换,根据页面的大小将物理存储器分成几个块。由于物理内存中的块空间是用于保存虚拟页面的容器,因此物理内存中的块称为页面帧。页面和页面框架是Linux实现虚拟内存技术的基础。
  虚拟内存页面,物理内存页面框架和页面表
  在Linux中,页面和页面框架的大小通常为4KB。当然,根据系统和应用程序,页面和页面框架的大小也可能不同。
  物理内存和虚拟内存分为页面框架和页面后,存储单元的原始地址自然分为两个部分,两个部分各自代表不同的含义:上部分段称为页面框架代码和页面编号, 分别。它们是标识页面框架和页面的代码;较低的位称为页面帧偏移和页面偏移,它们是页面帧和页面中的存储单元的地址码。下图显示了两段虚拟内存和物理内存分页后的情况:
  为了使系统在相应的页面框架中正确访问虚拟页面的图像,在将页面映射到页面框架时,用于存储页面图像的页面编号和页面框架代码必须填充到名为In的页面中。表格条目。此页表是前面提到的映射记录表。页表的示意图如下:
  在页面模式下,虚拟地址和物理地址转换关系的示意图如下:
  换句话说:处理器遇到的地址都是虚拟地址。虚拟地址和物理地址都被分成页码(页帧码)和偏移值。在将虚拟地址转换为物理地址的过程中,偏移值不会改变。页码和页面帧代码之间的映射在映射表——页表中。
  请翻页和交流
  虚拟页面到物理页面帧的映射称为页面加载。
  当处理器尝试访问虚拟内存页面时,它首先进入页面表以查询页面是否已映射到物理页面帧并记录在页面表中。如果是,则MMU将页码转换为页框码,并添加虚拟地址提供的页面的物理地址,以形成访问物理内存的物理地址;如果不是,则表示尚未加载虚拟内存页面。内存,那么MMU会通知操作系统:发生了页面访问错误(页面错误),然后系统会启动所谓的“请页面”机制,即调用相应的系统操作函数来判断是否虚拟地址有效。地址。
  如果它是有效地址,则它将地址所指向的页面从虚拟内存读入内存中的空闲页面帧,并在页面表中添加相应的条目。最后,处理器将生成页面错误。这个地方重新开始;如果它是无效地址,则表示进程正在尝试访问不存在的虚拟地址,操作系统将终止访问。当然,在成功应用页面之后,也存在内存中没有空闲物理页面帧的情况。也就是说,系统必须启动所谓的交换机制,即调用相应的内核操作函数,并在物理页面框中找到一个页面框架,该框架由不再使用或不使用的页面占用在不远的将来。找到后,将页面移出以加载新页面。移出页面根据两种情况处理:如果页面未被修改,则删除;如果页面已被修改,则系统必须将页面写回辅助存储。
  系统页面的处理如下:
  为了公平地选择将从系统中丢弃的页面,Linux系统使用最近最少使用(LRU)页面的老化算法。此策略根据系统中每个页面访问的频率为物理页面框架中的页面设置一个名为age的属性。访问页面的次数越多,页面越小;相反的是更大的。较旧的页面是要换出的页面的最佳候选者。
  快速观看
  每次系统访问虚拟页面时,都需要在内存的所有页面表中找到页面的页面框架,这是一项非常耗时的任务。但是,已经发现,一旦系统访问了一个页面,系统将在该页面上稳定地工作一段时间。因此,为了提高访问页表的速度,系统还配备了一组可以容纳页表的硬件寄存器,这样当系统访问虚拟内存时,它首先访问该组硬件寄存器。 ,系统速度快。太多了。保存当前页表的这组寄存器称为快速表。
  总之,在使用虚拟存储技术时,处理器必须配备一些硬件来承担一些内存管理任务。存储器管理任务的硬件部分称为存储管理单元MMU。存储管理单元MMU的工作过程如下:
  页面共享
  在多程序系统中,通常存在多个程序需要共享同一段代码或数据的情况。在分页管理的内存中,这是一件好事:让多个程序共享同一页面。
  具体方法是使这些相关程序的虚拟空间的页面指向页表中的存储器中的相同页面帧。因此,当程序运行并访问这些相关页面时,它访问同一页面框架中的页面,并且页面框架中的页面由这些程序共享。下图是共享单个页面的三个程序的示例:
  页面保护
  从上面可以看出,页表实际上是从虚拟空间到物理空间的入口点。因此,为了保护页面内容不被无法访问页面的程序破坏,应在页面表的条目中设置一些访问控制字段,以指示允许在内容中执行的操作。相应的页面,从而禁止非法访问。 。
  下图是在页表条目中存储控制信息的可能形式:注意:其中的PCD位指示是否允许高速缓存。
  如果程序试图在页面上执行禁止页面操作,则会导致操作系统中断。——非法访问被中断,操作被拒绝,从而保护页面内容不被破坏。
  多级页表
  应注意,页表是由操作系统创建的用于存储器管理的表。因此,当程序运行时,其页表也存储在存储空间中。如果一个程序只需要一个页面表,那就没问题了。但是如果程序的虚拟空间很大,就会出现一个大问题。
  例如,如果程序具有4 GB的虚拟空间和4 KB的页表,则该程序空间为1M页。为了存储这个1M页面的页面指针,这个页面表的长度非常大,并且内存的负担也很大。因Africa,最好将页面存储为页面。程序运行时,只将所需页面复制到内存中,暂时不需要的页面保留在辅助内存中。为了管理这些页表页,还创建了记录页表的顶部地址的页目录表,以便单级页表成为辅助页表。辅助页面表的地址转换如下图所示:
  当然,如果程序的虚拟空间较大,也可以使用三级页表进行管理。为了通用,Linux系统使用三级页表结构:页面目录(PGD),页面中间目录(PMD)和页面表(PTE)。
  Linux页表结构
  对于一般用途,Linux系统使用三级页表结构:页面目录,中间页面目录和页面表。 PGD是一个顶级页表,它是一组pgdt数据类型。每个数组元素指向一个中间页面目录; PMD是辅助页表,它是pmdt数据结构的数组,每个数组元素指向一个页表; PTE是一个页表,一个pte_t数据类型的数组,每个数据类型都包含一个物理地址。
  为了应用程序的灵活性,Linux使用一系列宏来掩盖各种平台的细节。用户可以根据自己的需要在配置文件配置中配置页表,以决定是使用三级页表还是二级页表。
  编译系统时,目录include/asm符号根据配置文件config中的配置连接到特定的CPU特定文件目录。例如,对于i386CPU,目录符号将连接到include/asm-i386,并且辅助页表的基本结构在文件pgable-2level-defs.h中定义,如下所示:它还定义了:
  #define PGDIR_SHIFT 22 //线性地址中PGD的起始地址为bit22
  #define PTRS_PER_PGD 1024 //PGD总共有1024个条目
  #define PTRS_PER_PTE 1024 //PTE条目总数为1024。
  #万一
  乡村)页面目录和页表条目的数据结构在文件include/signed-i386/raster目录中定义。
  Typedof struct {unsigned long pte_low; } pte_t; //页表中的物理地址,页框架代码
  Typedof struct {unsigned long pgd; } pgd_t; //指向页面表
  Typedof struct {unsigned long pgprot; } pgprot_t; //页表中的各种状态信息和访问权限
  根据定义,它们都是只有一种长类型(32位)的结构。
  注意:与上面的“页面保护”部分一样,页面帧代码表示物理地址,只有高20位就足够了(因为页面帧的长度为4 KB,页面偏移12位) 。接下来的12位可以存储各种状态信息和访问权限。但Linux并没有这样做。相反,它重新定义了一个存储它的结构,并通过OR操作将两者结合起来。
>
400-635-8089
立即
咨询
电话咨询
服务热线
400-635-8089
微信咨询
微信咨询
微信咨询
公众号
公众号
公众号
返回顶部