linux虚拟内存管理简要总结

以下讨论仅限i386 平台,一般考虑典型情况

  1. linux 内核对整个系统的物理内存是通过类型为struct page 的数组mem_map 来管理的。系统中的伙伴系统分配算法最终是通过操作这个数组来记录物理内存的分配、回收等操作。在这里不要被系统的高端内存、低端内存等概念搞混淆了,高、低端内存的分类主要在于区分物理内存地址是否可以直接映射到内核线性地址空间 中。

我们知道,linux 的内核地址空间大小为1G (用户空间0~3G ,内核空间3G~4G ,这种分法最常见),因此如果把这1G 线性地址空间全部拿来直接一一映射 物理内存的话,在内核态的所有进程(线程)能使用的物理内存总共最多只有1G, 为了能使在内核态的所有进程能使用更多的物理内存,linux 采取了一种变通的形式:它将1G 内核线性地址空间分为几部分,第一部分为1G 的前896M ,这部分内核线性空间与物理内存的0~896M 一一映射(相差一个为0xc0000000 的常数),后面128M 的线性空间拿来动态映射剩下的所有物理内存,由于动态映射的方法不一样,后面的128M 又分成了几个部分,有兴趣的可以查看相关资料。在这里,前面896M 线性空间对应的物理内存就是所谓的低端物理内存,剩下的物理内存就是高端物理内存。

从上面高、低端物理内存命名的由来我们可以知道,高、低端物理内存与具体的内存分配算法无关,它们都是被mem_map 数组控制起来,再由伙伴分配系统实施管理。

 

  1. 关于进程及其内存分配

首先要明白一个概念:进程中使用的所有地址都是虚地址,在linux 下这个虚地址就是所谓的线性地址。linux 中进程可运行在用户态和内核态,(典型配置情况下)当进程运行在用户态时,它使用的线性地址只能位于0~3G 范围内,当进程运行于内核态时,它使用的线性地址地址范围为3G~4G

为了把线性地址转化为物理地址,每个进程都有自己私有的页目录和页表。linux 在建立进程页目录时,把用户地址空间的页目录项(0~767 项)清空而将内核页目录表(swapper_pg_dir )的第768 项到1023 项拷贝到进程的页目录表的第768 项到1023 项中。由于内核在初始化时也只映射了物理内存的前896M ,我们可以知道内核也目录表只能保证第768 项开始的224 项中有有效映射。从这里我们可以知道,所有的进程都共享了其内核线性地址空间

当一个进程在内核空间发生缺页故障的时候,这主要发生在访问内核空间动态映射区线性地址,在其处理程序中,就要通过0 号进程的页目录(swapper_pg_dir )来同步本进程的内核页目录,实际上就是拷贝0 号进程的内核页目录到本进程中(内核页表与进程0 共享,故不需要复制)。如果进程0 的该地址处的内核页目录也不存在,则出错,具体代码可以参考vmalloc 的实现源码。

当进程运行于用户态时,若其需要申请内存空间,内核首先会在其用户线性空间中分配需要的线性地址空间,再通过伙伴分配系统分配物理内存并把分配的物理内存跟用户空间线性地址映射起来,最后再修改进程的页目录项及页表项写入这些映射关系。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值