首页 > 代码库 > 内存寻址二(分页)

内存寻址二(分页)

硬件中的分页

概念

分页单元(paging unit)把线性地址转换成物理地址。其中一个关键任务是把所请求的访问类型与线性地址的访问权限相比较,如果这次内存访问时无效的,就产生一个缺页异常。

为了效率起见,线性地址被分成以固定长度为单位的组,称为页(page)。页内部连续的线性地址被映射到连续的物理地址中。这样,内核可以指定一个页的物理地址和其存取权限,而不用指定页所包含的全部线性地址的存取权限。通常使用术语"页"既指一组线性地址,又指包含在这组地址中的数据。

分页单元把所有的RAM分成固定长度的页框(page frame)(有时称作物理页)。每一个页框包含一个页(page),也就是说一个页框的长度与一个页的长度一致。页框是主存的一部分,因此也是一个存储区域。区分一页和一个页框是很重要的,前者只是一个数据块,可以存放在任何页框或磁盘中。

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


Intel分页模式

分页行为通过下面的控制位控制:

a、The WP and PG flags in control registerCR0 (bit 16 and bit 31, respectively).

b、The PSE, PAE, PGE, PCIDE, and SMEP flags in control registerCR4 (bit 4, bit 5, bit 7, bit 17, and bit 20 respectively)

c、The LME and NXE flags in theIA32_EFER MSR (bit 8 and bit 11, respectively).

只有在保护使能(CR0.PE = 1),分页才会使能(CR0.PG = 1),如果分页使能,有三种分页模式,CR4.PAE与IA32_EFER.LME决定使用哪种分页模式

If CR0.PG = 1 and CR4.PAE = 0, 32-bit paging is used.

If CR0.PG = 1, CR4.PAE = 1, and IA32_EFER.LME = 0, PAE paging is used.

If CR0.PG = 1, CR4.PAE = 1, and IA32_EFER.LME = 1, IA-32e paging is used.


32bit分页

常规4KB分页

32位的线性地址被分成3个域:

Directory(目录)   Table(页表)   Offset(偏移量)

最高10位          中间10位       最低12位

线性地址的转换分为两步完成,每一步都基于一种转换表,第一种转换表称为页目录表(page directory),第二种转换表称为页表(page table)。


正在使用的页目录的物理地址存放在控制器寄存器CR3中。线性地址内的Directory字段决定页目录中的目录项,而目录项指向适合的页表。地址的Table字段依次又决定页表中的表项,而表项含有页所在页框的物理地址。Offset字段决定页框内的相对位置。由于它是12位长,故每一页含有4096字节数据。

Directory字段和Table字段都是10位长,因此页目录和页表都可以多达1024项。那么一个页目录可以寻址到高达1024*1024*4096=2^32个存储单元。

扩展4M分页(extended paging)

扩展分页用于把大段连续的线性地址转换为相应的物理地址,在这种情况下,内核可以不用中间页表进行地址转换,从而节省内存并保留TLB项


扩展分页和常规分页的页目录项基本相同,除了:

a、Page Size标志必须被设置。

b、20位物理地址字段只有最高10位是有意义的。这是因为每一个物理地址都是在以4M为边界的地方开始的,故这个地址的最低22位为0。

下面是page directory,page table及cr3字段代表的意义





举例:

假如内核已给一个正在运行的进程分配的线性地址空间范围是0x20000000到0x2003ffff。假设进程需要读线性地址0x20021406中的字节。这个地址由分页单元按下面的方法处理:

1.Directory字段的0x80用于选择页目录的第0x80目录项,此目录项指向和该进程的页相关的页表

2.Table字段0x21用于选择页表的第0x21表项,此表项指向包含所需页的页框。

3.最后,Offset字段0x406用于在目标页框中读偏移量为0x406中的字节。


物理地址扩展(Physical Address Extension,PAE)分页

大型服务器需要大于4G的RAM来同时运行数以千计的进程,所以必须扩展32位80x86架构所支持的RAM的容量。Intel通过在它的处理器把地址总线管脚从32增加到36以满足这种需求,为了把32位线性地址转换为36位物理地址引入一种新的分页机制PAE。

引入一个叫做页目录指针表(Page Directory Poninter Table,PDPT)的页表新级别,它有4个64位表项组成。

当把线性地址映射到4KB的页时,32位地址按下列方式解释:

cr3     指向一个PDPT

位31-30 指向PDPT中4个项中的一个

位29-21 指向页目录中512个项中的一个

位20-12 指向页表中512项中的一个

位11-0  4KB页中的偏移量


当把线性地址映射到2MB的页时,32位线性地址按下列方式解释

cr3     指向一个PDPT

位31-30 指向PDPT中4个项中的一个

位29-21 指向页目录中512个项中的一个

位20-0  4KB页中的偏移量


使用PAE的主要问题是线性地址仍然是32位长。这就迫使内核编程人员用同一线性地址映射不同的RAM区。


64位系统中的分页(IA-32e Paging)

32位处理器普遍采用两级分页。然而两级分页并不适用于采用64位系统的计算机。原因如下:

首先假设一个大小为4KB的标准页,4KB覆盖2^12个地址,所以offset字段是12位。如果我们现在决定仅仅使用64位中的48位来寻址(这个限制仍然能是我们自在地拥有256TB的寻址空间!),剩下的48-12=36位被分配给Table和Directory字段。如果我们决定为两个字段个预留18位,那么每个进程的页目录和页表都含有2^18个项,即超过256000个项。

由于这个原因,所有64位处理器的硬件分页系统都使用了额外的分页级别。使用的级别数量取决于处理器的类型。

平台名称   页大小   寻址使用位数   分页级别   线性地址分级

alpha     8KB     43           3        10+10+10+13

ia64      4KB     39           3        9+9+9+12

ppc64     4KB     41           3        10+10+9+12

x86_64    4KB     48           4        9+9+9+9+12

注:ia64是intel的一门高端技术,不与x86_64系统兼容

IA-32e Paging机制下线性地址映射到4KB的页