Linux内核内存管理概述

108次阅读
没有评论

共计 2224 个字符,预计需要花费 6 分钟才能阅读完成。


通常在计算机系统中,虚拟页被称为页,物理页被称为页帧或页框。虚拟页是进程或程序地址空间的抽象,它们被映射到物理页帧或页框上。虚拟页的使用可以让进程或程序使用比实际物理内存更大的地址空间,从而提高计算机系统的性能和效率。

内存的管理是以内存页面为单位进行的,一个内存页面是指连续的4KB物理内存

Intel 80×86 CPU中,程序在寻址过程中使用的是由段+偏移值构成的地址,该地址不能直接用于直接寻早物理地址因此又被称之为虚拟地址。

而将虚拟机地址变换为物理地址的这种地址变换机制为内存管理的主要功能之一,另一个主要功能为:内存寻址保护机制

Linux内核内存管理概述

1. 内存分页管理

分页管理的目的是:将某一物理地址页面映射到某一线性地址

在 x86系统中,内存分页管理是通过页目录表以及内存页表的二级表组成 ,其中页目录表与页表的结构相同,表项结构也相同

页目录表中的每一个表项(4B)用来寻址一个页表,而每个页表的表项(4B)用来寻址一个物理内存页.即是当唯一指定一个页表目录项与页表项我们就可以唯一地对应一个物理内存页

一个系统中可以同时存在多个页目录表,而在某一时刻只有一个页目录表可用其由CR3寄存器保存物理内存地址

页目录表占一页内存(4KB),则最多可以寻址(4KB/4B=1024)个页表,页表亦如此。所以一个页目录表所寻址的所有页表共可以寻址 1024\*1024\*4096B=4GB内存空间
Linux内核内存管理概述

1.1. 页目录与页表项结构

由于内存页的大小是4KB,也就是2的12次方字节,因此内存页的地址必须是4KB的倍数,即低12位总是0。这是因为在二进制中,2的12次方等于4096,即1000000000000,低12位全是0。因此,内存页的起始地址总是位于4K边界上,其低12位总是0。

因此页表项的低12位可做他用

这种对齐方式可以提高内存管理的效率和性能,因为如果内存页不对齐,那么将会出现跨页的情况,导致内存访问效率下降,甚至产生错误。通过将内存页对齐到4K边界上,可以最大限度地利用内存空间,同时提高内存访问的效率和性能。
  • 在一个页目录表中,其页帧地址指向页表的起始地址;而在二级页表中,页帧地址指向期望内存操作的物理内存页地址
  • 存在位(PRENSENT—P)确定一个页表是否可以用作地址转换过程

当CPU试图将一个页表项进行地址转换时,如果P=0,则会抛出页异常信号。此时缺页中断就将所请求的页加入到物理内存中,并且导致异常的指令将会重新执行

  • 读写位(READ/WRITE—R/W)与用户/超级用户(USER/SUPERVISOR—U/S)用于分页级别的保护机制
  • 已访问位(ACCESS—A)和已修改(DIRTY—D)用来提供有关页的使用信息(页目录项没有D位,页表项有D位)
Linux内核内存管理概述

1.2. 线性地址变换

对于内核或者应用进程,在申请内存时使用的是线性地址

为了使用分页机制,一个32位的线性地址被分为3部分:页目录项、页表项、对应物理内存页的偏移地址(在进行内存分页时,页内偏移地址是存放在虚拟地址的低位部分,用于在地址变换过程中确定所访问的页内具体位置)

Linux内核内存管理概述
Linux内核内存管理概述

2. linux中的物理内存管理与分配

其中,主内存区即为程序进行分配管理内存区域

Linux内核内存管理概述

每个进程在地址中都是从nr*64MB地址起始,nr是任务号,占用逻辑地址64MB;bss为未初始化的数据段;环境参数数据块最长128KB,其左面为起始堆栈指针

Linux内核内存管理概述

2.1. 页面出错异常处理

在开启了分页机制(标志寄存器中PG=1)的情况下,存在以下两种情况使得引起页出错异常中断 INT 14

  1. 页目录项或者页表项存在位P=0//缺页中断
  2. 当前执行程序权限不够访问该页面//写保护中断

此时CPU将会提供以下信息:

  1. 栈中的出错码(error code)

其格式位32位,但仅最低三位有用,分别指P、R/W、U/S位;详见P745\

  1. 控制寄存器CR2将保存引起异常的线性地址。页出错处理程序可使用其定位相关页目录项与页表项

2.2. 写时复制

当进程A调用fork()函数创建进程B时,两个进程实际上是共享A的物理页面;fork会让子进程以只读方式共享父进程A页面,同时将A进程对于该物理页面的访问也设置为只读模式

当其中一方进行写操作时将会触发页面异常中断,此时 CPU将会执行 do_wp_page() 来解决该异常:① 取消该页面的共享;② 为写进程复制一个新的物理页面;③ 重新执行导致页面异常的写入操作


2.3. 需求加载机制

需求加载(Demand Loading)是指仅当程序需要时才将程序代码和数据从磁盘加载到内存中,而不是在程序启动时将所有代码和数据都加载到内存中。这种机制可以减少内存使用,提高系统性能和效率。

1. 程序启动时,操作系统会将程序的可执行文件加载到进程的地址空间中,但是只有程序的代码和一些必要的数据被加载到内存中,而其他数据则被标记为未加载状态,只有在需要时才会被加载到内存中。
2. 当程序需要访问未加载到内存中的数据时,操作系统会触发一个页错误(Page Fault)异常,告诉操作系统需要将该数据加载到内存中。操作系统会检查该页是否在磁盘交换区中,如果在,则将该页从磁盘交换区中读入内存,并更新页表中的映射关系。
3. 加载完数据后,程序继续执行,直到下一次访问未加载到内存中的数据,再次触发页错误异常,从而触发新一轮的需求加载过程。

此种技术要求被执行的文件目标格式为ZMAGIC——需求分页格式的目标文件格式(程序的代码段与数据段都从页面边界开始存放),以契合内核以页面为单位读取代码或者数据

正文完
 
honghai
版权声明:本站原创文章,由 honghai 2023-10-14发表,共计2224字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)