Linux内存管理详情

Linux内存管理

1 物理内存

Linux内核为了有效的使用机器中的物理内存,在系统初始化的阶段将物理内存划分为几个功能区域。
在这里插入图片描述

如上图所示,内存的开始部分是内核源码,这部分是ROM;接下来是告诉缓冲区,缓冲区的作用在杂学中记录,告诉缓冲区是RAM。高速缓冲区中间640K-1M的空间留作显存和BIOS程序,这部分也是ROM。再往后就是主内存了,也就是通常说的系统内存,这部分是RAM。

物理内存空间是有限的,因此CPU通常提供两种内存管理模式来更有效的利用内存:内存分段机制和内存分业机制,其中内存分页模式是可选像。在Linux内核中,使用了这两种内存机制管理内存。


2 内存地址空间概念

  • 进程的虚拟和逻辑地址
  • CPU的线性地址
  • 实际的物理地址

虚拟地址是指由程序产生的由段选择符和段内偏移地址两个部分组成的地址。虚拟地址由GDT映射的全局地址空间和LDT映射的局部地址空间组成。选择符的索引部分由13位比特表示,加上GDT和LDT的1位,因此80x86 CPU可以索引16384个选择符,如果每个段的长度都是4G的话,那么虚拟地址空间可以达到4G*16384=64T


逻辑地址也是由程序产生的与段相关的偏移地址部分。在保护模式下,逻辑地址就是程序代码段限长内的偏移地址。
注意:逻辑地址也就是代表着进程可用的地址空间,因为段描述符指向的是物理内存段地址,相当于一个其实地址,而逻辑地址,在保护模式下也就是偏移地址表示的是进程可用的内存地址空间大小。



问题:如上所述,段内偏移地址和逻辑地址是否是一个概念。

答:在实模式,偏移地址就是逻辑地址。因为实模式下没有分段机制,物理地址就是逻辑地址(也称虚拟地址)

在保护模式下,有了分段的概念,偏移地址叫做段内偏移地址,而逻辑地址由段选择符和段内偏移地址组成。其中偏移地址是相对于基地址的偏移量。

拓展:实模式和保护模式的概念

实模式:最早的x86cpu就是工作在实模式,使用的物理内存,地址总线为20跟,可访问的内存大小为2的20次幂=1M,所有的程序都可以随意访问这1M的内存空间,很容易造成内存冲突。

保护模式:现代计算器cpu全部工作在保护模式下,保护模式支持虚拟内存,使用内存分页管理机制,将物理内存映射到虚拟内存空间,从而实现内存的抽象和隔离。



线性地址:现代计算机中,x86架构都有内存分页机制和分段机制。

内存分段机制将线性地址分解成段选择子和段内偏移地址,段选择子在全局描述符中查找相应的段描述符,和段内偏移地址组成一个虚拟地址。

内存分页机制将线性地址分解成页目录、页表偏移量和页内偏移量。其中页目录和页表偏移量用来得到页的物理内存,然后通过页内偏移量相加得到最终的物理地址。


进程是如何使用虚拟内存的呢?下面是进程使用一个虚拟内存查询数据的过程:

首先,一个程序调用一个并不存在的内存时,CPU需要一种方式来知道程序使用了虚拟内存,cpu采取页错误异常中断来实现,将这个错误地址的线性地址存到CR2寄存器上。那么系统在处理中断的时候就会发现使用了虚拟内存,且得知了具体的内存地址,然后通过分页机制将地址分解成页目录、页偏移量和页内偏移量,通过上段描述的方式计算出最终物理内存,并将要求的页面从二级缓存加载到内存中,如果此时物理内存全部被占用,那么可以借助交换缓冲区(swap)将物理内存中暂时不使用的页面交换到二级缓存中。然后把要求的页面掉入内存中。这就是内存管理的缺页加载机制。在0.11Linux内核中是在程序mm/memory.c中实现。
在这里插入图片描述

段存放基地址、段的长度值和段的访问特权级别等信息。寻址的内存位置由段描述符指定的段基地址和段内偏移值组成。段的长度是可变的,由段描述符中段长度指定。
在这里插入图片描述


内存分页机制,我们围绕着下图进行分析内存分页的过程,如何从线性地址转换成物理内存地址:
在这里插入图片描述
如上图所示,线性地址就是程序访问的虚拟地址,首先,每个进程的虚拟内存空间有许多页目录表,而CR3寄存器存储的是页目录表的物理地址。线性地址的高10位找到页目录表中的页目录项,然后在页表中,通过虚拟地址的中10位找到相应的页表项,此时已经对应上物理内存的页了,再通过虚拟地址的低12位(页内偏移量)找到最终的物理地址。需要知道的是,在Linux0.11内核中,每个进程最大的虚拟地址空间是64M。


在Linux0.11中,每个进程的虚拟内存空间大小是64M,允许用户自定义的任务64个,因此全部任务能使用的最大虚拟地址空间是64*64M=4G。且Linux0.11内核,不管是内核进程还是用户进程,其使用的代码段、数据段、堆栈段都是互相重合的。这里需要和CPU的代码段和数据段分开,CPU的代码段和数据段是可以设置在4G线性地址空间的任意地方,而且它们可以重叠、独立、部分重叠。


总结:Linux的内存管理离不开两个机制–分段机制和分页机制,借助下图总结下一个进程从使用虚拟地址到获取数据的全过程。
在这里插入图片描述
首先进程使用的虚拟地址是通过分段机制而来的,由于虚拟内存,使得每个进程感觉自己独占所有的系统内存资源,在执行程序时,CPU通过段基址寄存器和段内偏移量构造出一个虚拟地址,然而这个地址在系统内存中是不存在的,因此访问这个虚拟地址的时候会报错,内存错误中段,这个错入地址会被CPU存入CR2中断寄存器中,系统在处理中断的时候就会拿到这个虚拟地址,然后通过分页机制,结合CR3寄存器中的页目录项地址,找到对应的物理页地址的映射地址页(也即页表项地址),这个页表项地址就是物理页的基地址,再通过页内偏移量计算出最终的物理地址。然后将页面数据从磁盘空间加载到此物理页面,并返回此物理地址。程序就可以访问内存中的数据了。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值