日期:2014-05-16  浏览次数:20586 次

linux 内存管理



?1、 进程的 4G 线性空间被划分成三个部分:进程空间( 0-3G )、内核直接映射空间( 3G – high_memory )、内核动态映射空间( VMALLOC_START - VMALLOC_END

2、 三个空间使用同一张页目录表,通过 CR3 可找到此页目录表。但不同的空间在页目录表中页对应不同的项,因此互相不冲突

3、 内核初始化以后,根据实际物理内存的大小,计算出 high_memory VMALLOC_START VMALLOC_END 的值。并为“内核直接映射”空间建立好映射关系,所有的物理内存都可以通过此空间进行访问。

4、 “进程空间”和“内核动态映射空间”的映射关系是动态建立的(通过缺页异常)

假设在有三个线性地址 addr1, addr2, addr3 ,分别属于三个线性空间,但是最终都映射到物理页面 1

1、 三个地址对应不同的页表和页表项

2、 但是页表项的高 20bit 肯定是 1 ,表示物理页面的索引号是 1

3、 同时,根据高 20 bit ,可以从 mem_map[] 中找到对应的 struct page 结构, struct page 用于管理实际的物理页面(红线)

4、 从线性地址,根据页目录表,页表,可以找到物理地址

5、 Struct page 和物理地址之间很容易互相转换

6、 从物理地址,可以很容易的反推出在内核直接映射空间的线性地址(蓝线)。要想得到在进程空间或者内核动态映射空间的对应的线性地址,则需要遍历相应的“虚存区间”链表。

关于页目录表:

1、 每个进程有一个属于自己的页目录表,可通过 CR3 寄存器找到

2、 而内核也有一个独立于其它进程的页目录表,保存在 swapper_pg_dir[] 数组中

3、 当进程切换的时候,只需要将新进程的页目录把地址加载到 CR3 寄存器中即可