linux内存管理机制详解,linux内存管理详解


内存管理机制

linux系统支持多任务,多进程的,这样CPU以及其他硬件的利用率就会更高,这个时候就要考虑到将系统的有限的物理内存如何及时有效的分配给多个程序,这个事情本身称之为内存管理

内存管理需要解决的三个问题:

1.进程空间不能隔离:由于程序直接访问的是物理内存,所以程序所使用的内存空间不是隔离的。

2.内存使用的效率低:我们有三个程序,程序1,2,3.程序1运行的过程中需要10M内存,程序2运行的过程中需要100M内存,而程序3运行的过程中需要20M内存。假如我们要让三个程序同时运行,唯一的方法就是使用虚拟内存技术将一些程序暂时不用的数据写到磁盘上,在需要的时候在从磁盘读回内存。但在将数据从磁盘读到内存时,IO操作比较耗时,从而导致效率低下

3.程序运行的地址不能确定:程序每次运行时都要在内存中分配一块足够大的内存区域,但是这个空闲的位置是不确定的

内存管理的方法:

现在内存管理的方法就是在程序物理内存之间引入虚拟内存的概念,每个程序都有自己独立的内存地址空间,这样就做到了进程隔离。这里的进程地址空间指的是虚拟地址。既然在程序与物理地址之间增加了虚拟地址,那么就要解决从虚拟地址到物理地址之间的映射,程序最终还是要运行到物理内存的。

而这种映射方式就是分段和分页技术。分页机制的实现需要硬件的实现,而这个硬件的名字就叫做MMU,它专门负责把虚拟地址转换为物理地址,也就是从虚拟页找到物理页。

基本概念:

物理地址:内存芯片级的单元寻址,与处理器和CPU连接的地址总线相对应

虚拟内存:是对整个内存的抽象描述,称为虚拟内存。进程使用虚拟内存中的地址,由操作系统把它转换成真正的物理地址。有了这个抽象,一个程序就可以使用比真实地址大得多的地址空间。甚至多个进程可以使用相同的地址(转换后的物理地址不一定相同)

逻辑地址:逻辑地址指的是机器语言指令中,用来指定一个操作数或者一条指令的地址。一个逻辑地址是由一个段标识符加上一个指定段内相对地址的偏移量来表示。

线性地址:也叫虚拟地址,不是真实的地址,如果逻辑地址是对应硬件平台段氏管理转换前的地址,那么线性地址就是对应了硬件页式内存的转换前地址

CPU将一个虚拟内存空间的地址转换为物理地址的步骤:

1.首先给定一个逻辑地址(段内偏移量)

2.CPU要利用其段氏内存管理单元,先将逻辑地址转换为线性地址,在利用其页式内存管理单元,转换为最终的物理地址

linux CPU页式内存管理:CPU页式内存管理单元负责把一个线性地址(虚拟地址)转化为一个物理地址。线性地址(虚拟地址)被分为以固定长度的组,称之为页。例如:一个32位的机器线性地址(虚拟地址)最大为4G,可用4KB为一页来划分,总共被划分为一个具有2的20次方的大数组。这个大数组称之为页目录。为了保证物理内存能得到充分的利用,内核会在适当的时候将物理内存中不常用的数据块自动交换到虚拟内存中,而将经常使用的信息保留到物理内存。

概念:

页目录:32位,虚拟地址4G,以4KB划分为2的20次方的大数组,这个大数组称之为 “页目录”,页目录是唯一的,它的地址放在CPU的次cr3寄存器中,是进行地址转换的开始。

页表:在虚拟内存中,页表是个映射表的概念,把线性地址(虚拟地址)映射到物理地址的数据结构称之为页表,页表存放在主存中,并在启用分页单元之前必须由内核对页表进行适当的初始化

页:页分为两种,一种是虚拟地址的页,即虚拟地址被分为固定长度单位的组,称之为页,物理内存被划分为固定长度的管理单位,称之为页(物理页(页框,页帧))

页式管理的具体流程:

1.分页单元中,页目录的地址放在CPU的CR3寄存器中,是进行地址转换的起始点。

2.每个进程,都有其独立的虚拟地址空间,运行一个进程,首先需要将它的页目录地址放到CR3寄存器中,将他的进程保存下来

3.每个32位线性地址被划分为三部分:页目录索引(10位),页表索引(10位),偏移(12位)“也就是说:页目录有2^10页表,每个页表有2^10页,每个页有2^12个字节”

转换步骤:

第一步:转入进程的页目录地址(操作系统在调度进程时,把这个地址装入CR3)

第二步:根据线性地址前十位,找到对应的索引项——页表地址

第三步:根据线性地址中间十位,在页表中,找到相应的索引项——页的起始地址

第四步:将页的起始地址与线性地址最后12位相加,得到物理地址

IO空间与内存空间:

每个外设都是通过读写他们的寄存器来控制的,一般一个设备会有不止一个寄存器,并且在连续地址存取它们,这些寄存器位于IO空间时,称为IO端口。位于内存空间时,称为IO内存。即便像x86处理器中,虽然提供了IO空间,但我们设计电路板时仍可以只将寄存器涉及到内存空间。此时CPU向访问一个内存单元一样访问外设IO端口,而不需要设立专门的IO指令

IO空间:IO空间与内存是独立的,它们有各自的总线,并且IO空间一般为64K,采用IN和OUT指令进行访问内存空间:大小为4G,两者差别很大

IO端口:外设寄存器也成为IO端口,通常包括“控制寄存器,状态寄存器,和数据寄存器”,外设的寄存器通常是连续的编址,但是外设寄存器和CPU核心寄存器不同的是外设寄存是有地址的,不同的CPU芯片会有不同的总线连接方式,所以也会有不同的外出寄存器地址,知道地址之后就可以通过对外设对应的寄存器地址赋值来控制外设。

CPU对IO端口物理地址的编址方式有两种:一种似IO映射方式,也称为端口映射。另一种是存储空间映射方式,称为内存映射。

一类CPU(Power PC,ARM等)这些外设寄存器看做内存的一部分,寄存器参与内存统一编址,通过一般的内存指令来访问这些外设寄存器,称为IO内存

另一类CPU(x86)把这些外设寄存器看做是一个独立的地址空间,访问内存的指令不能用这些外设寄存器,而需要用专用的指令(IN,OUT指令),称为IO端口

相关内容