## 硬件中的分页:
32位的线性地址被分成3个域:
高10位:页目录表
中间10位:页表
低12位:页表内偏移
使用二级页表模式的目的在于减少每个进程页表所需RAM数量。如果是一级页表,则需高达220个表项,而二级模式只为进程实际使用的那些虚拟内存区请求页表。
页目录项和页表项有同样的结构,均包含了一些属性字段。
评:段页属性字段的设置很有意义,分段、分页这种将内存结构化、组织化的方式,同时可以增加对某一段或页的属性描述信息,对于内存管理来说很有意义,这种组织内存的方法思路,正如行政区域的划分。
### 物理地址扩展(PAE)分页机制:
这一部分在我的另一篇博文中有提到:[http://blog.csdn.net/crazyingbird/article/details/7175559](http://blog.csdn.net/crazyingbird/article/details/7175559)
### 硬件高速缓存:
为了缩小CPU和RAM之间的速度不匹配,引入了硬件调整缓冲内存。
多处理器系统的每一个处理器都有一个单独的硬件高速缓存,它们需要额外的硬件电路,用于保持不同CPU之间的高速缓存内容的同步。只要一个CPU修改了它的硬件高速缓存,它就必须检查同样的数据是否包含在其它的硬件高速缓存中,如果是,它必须通知其它CPU用适当的值对其更新,这种活动叫做高速缓存侦听。这些活动由硬件处理,内核无需关心。
Linux对于所有的页框都启用高速缓存,对于写操作总是采用加回写策略。
### 转换后援缓冲器:
记录上一次线性地址转换得到的相应的物理地址,以便以后对同一线性地址的引用可以快速地得到转换。
在多处理器系统中,每个CPU都有自己的TLB,称为该CPU的本地TLB,与硬件高速缓存相反,TLB中的对应项不必同步,这是因为运行在现有CPU上的进程可以使同一线性地址与不同物理地址发生联系。
## Linux中的分页:
在2.6.10版本及之前,Linux采用三级分页模型,从2.6.11版本开始,采用四级分页模型:
* 页全局目录(Page Global Directory)
* 页上级目录(Page Upper Directory)
* 页中间目录(Page Middle Directory)
* 页表(Page Table)
对于没有启用物理地址扩展的32位系统,Linux取消了页上级目录和页中间目录,仅使用了两级页表。
启用了物理地址扩展的32位系统,Linux取消了上级目录,使用三级页表。
对于64位系统,Linux根据硬件对线性地址位的划分来决定采用三级或者四级页表。
### 物理内存布局:
Linux内核安装在RAM中从物理地址0x00100000开始的地方,也就是从第二个MB开始。
页框0由BIOS使用,存放加电自检期间检查到的系统硬件。
物理地址从0x000a0000到0x000fffff的范围通常留给BIOS全程,并且映射ISA图形卡上的内部内在。
第一个MB内的其它页框可能由特定计算机模型保留。
在启动过程的早期阶段,内核询问BIOS并了解物理内存的大小,随后,内核建立物理地址映射。
内核可能不会见到BIOS报告的所有物理内存:如果未启用PAE支持来编译,即使有更大的物理内存可供使用,内核也只能寻址4GB大小的RAM。
### 进程页表:
进程的线性地址空间分成两部分:
从0x00000000到0xbfffffff的线性地址,无论进程运行在用户态还是内核态都可以寻址;
从0xc0000000到0xffffffff的线性地址,只有内核态的进程才能寻址;
当进程运行在用户态时,它产生的线性地址小于0xc0000000;当进程运行在内核态时,它执行内核代码,所产生的地址大于等于0xc0000000。但某些情况下,内核为了检索或存放数据必须访问用户态线性地址空间。
### 内核页表:
内核维持着一组自己使用的页表,驻留在所谓的主内核页全局目录中,系统初始化后,这组页表还从未被任何进程或者任何内核线程直接使用;确切的说,主内核页全局目录的最高目录项部分作为参考模型,为系统中每个普通进程对应的页全局目录提供参考模型。
那么,内核如何初始化自己的页表呢?内核映像刚刚被装入内存后,CPU仍然运行于实模式,所以分页功能没有被启用。
第一阶段,内核创建一个有限的地址空间,包括内核的代码段和数据段、初始页表和用于存放动态数据结构的共128KB大小的空间。这个最小限度的地址空间仅够将内核装入RAM和对其它初始化的核心数据结构。
第二阶段,内核充分利用剩余的RAM并适当建立分页表。
由内核页表所提供的最终映射必须把从0xc0000000,即第四个GB开始的线性地址转化为从0开始的物理地址。
### 固定映射的线性地址:
固定映射的线性地址基本上是一种类似于0xffffc000这样的常量线性地址,其对应的物理地址不必等于线性地址减去0xc000000,而是可以以任意方式建立。因此,每个固定映射的线性地址都映射一个物理内存的页框。内核使用固定映射的线性地址来代替指针变量。
每个固定映射的线性地址都存在线性地址第四个GB的末端。
### 处理硬件高速缓存:
为了使高速缓存的命中率达到最优化,内核在下列决策中考虑体系结构:
一个数据结构中最常使用的字段放在该数据结构内的低偏移部分,以便它们能够处于高速缓存的同一行中。
注:聚集存储的数据结构大小可能大于行的大小。
当为一大组数据结构分配空间时,内核试图把它们都存放在内存中,以便所有高速缓存行按同一方式使用。