Windows内核(11)——分页机制(2-9-9-12)
Windows
分页机制 2-9-9-12
名词解释:
PTE(Page Table Entry):页表项
- PTE是页表中的一个条目,用于存储一个页面的物理地址和一些控制信息,比如页面是否有效、是否可读写等。通过页表,可以将虚拟地址转换为物理地址。
PDE(Page Directory Entry):页目录项
- PDE是页目录中的一个条目,用于指向一个页表。每个PDE包含指向页表的物理地址和控制信息。页目录本身是一个包含多个PDE的表,用于管理多个页表。
PTT(Page Table):页表
- 页表是一个结构,包含多个PTE。每个PTE指向一个物理页的地址。页表用于虚拟地址到物理地址的转换。在分层页表结构中,一个页表对应一个页目录项。
PDI(Page Directory Index):页目录索引
- PDI是虚拟地址的一部分,用于索引页目录中的某个PDE。通过PDI,操作系统可以找到页目录中对应的PDE,从而找到指向的页表。
页目录索引(PDI, Page Directory Index):用于查找页目录中的某个页目录项(PDE)。
页表索引(PTI, Page Table Index):用于查找页表中的某个页表项(PTE)。
页内偏移(Offset):用于定位物理页内的具体字节。
控制寄存器
CR(Control Register)控制寄存器,这些寄存器只能在0环使用
寄存器名称 | 描述 |
---|---|
CR0 | 包含处理器标志控制位,例如PE,PG,WP等 |
CR1 | 保留 |
CR2 | 专门用于保存缺页异常时的线性地址 |
CR3 | 保存进程页目录地址,切换进程用 |
CR4 | 扩展功能(如判断物理地址扩展模式等),Pentium系列(包括486的后期版本)处理器中才实现 |
CR0寄存器:
PE:启用保护模式标志,1是保护模式,0是实模式,这个位只是开始或关闭段机制,并没有启用分页机制。
PG:分页机制开关,在启用之前需要确保PE是开启的,否则会出现异常。
WP:写保护标志,禁止0环程序向3环只读页面执行写操作,也就是说当CPL<3的时候,如果WP=0,可以读写任意物理页,只要线性地址有效,如果WP=1,可以读取任意用户级物理页,但是对于只读的物理页,不能写 。
CR4寄存器
PAE (Physical Address Extension,物理地址扩展):
启用PAE可以使处理器支持超过4GB的物理内存寻址能力,增加到36位地址总线,从而支持高达64GB的物理内存。PAE=1开启
启用PAE后,页表结构会发生变化,使用三级页表:页目录指针表(PDP)、页目录(PD)和页表(PT)。
在启动选项 /nopae /pae 分别是关闭和开启PAE标志的指令
PSE (Page Size Extension,页大小扩展) :
PSE标志位是CR4寄存器的第4位(CR4.PSE)。启用PSE可以使处理器支持4MB的大页,从而减少页表开销,提高内存管理效率。 启用PSE后,页表结构中的页目录项(PDE)可以指向一个4MB的大页,而不是传统的4KB小页。
这个表列举了标志位组合起来的情况,(PS(在PDE里面)这个属于页表的标志位)
为什么放弃10-10-12分页机制?
参考: 80x86 2-9-9-12分页 - zpchcbd - 博客园 (cnblogs.com)
首先10-10-12分页模式这个成品是基于设计者的想法而产生的,先要确定的肯定是页的大小也就是4kb大小,那么也就是2^12 -> 4KB大小
那么还剩下”10” “10” 接着又设计PDE和PTE,通过PTE的前20位再加上12位的偏移,那么也就是4G寻址范围(那当时的情况寻址能力已经能足够了)
But,计算机在发展,4G的寻址能力无法满足越来越大的内存,所以开启了新的2-9-9-12分页机制
有什么办法在32位cpu下如何能够提高物理地址的寻址范围呢?
这里就引入了2-9-9-12的分页模式,又被叫做为PAE物理地址扩展
1、页的大小是确定的,4KB不能随便改,所以低12位是可以确定的
2、如果想增大物理内存的访问范围,就需要增大PTE,增大多少了呢?需要找到64G,那么增大到36位,但是还需要考虑对齐的因素,所以对齐到8个字节
知识点:在Windows系统中,对齐大小有利于高效率的执行和搜索
2-9-9-12分页结构
1.页的大小是确定的,4KB不能随便改,所以32位的最后一部分就确定为了12位。
2.如果想增大物理内存的访问范围,就需要增大PTE,增大了多少呢? 需要找到64G,那么增大到36位,考虑对齐的因素,增加到8个字节
由于PTE增大了,而PTT表的大小没变,依然是4KB,所以每张PTT表能放的PTE个数由原来的1024个减少到512个,512等于2的9次方,因此PTI=9
3.由于2的9次方个PDE就能找到所有的PTT表,因此PDI=9
4、同理PDI也是2的9次方 32 - 9 - 9 - 12 还差2位 所以就再做一级叫PDPI(页目录指针表)
知识点:这里需要让PDI也是2的9次方的原因,其实也是就是为了通过PDE同样可以定位到PTE,举个例子,此时2-9-9-12分页下,当前的PTE的前24位是4GB范围以外的,那么如果PDE不是跟PTE同样的结构,那么PDE的前24位就没有,也就是无法找到4GB范围以外,所以为了能够让PDE能够定位到4GB以为的PTE,所以也需要”9”
表结构
PDE结构:
(PS=1为大页的情况下)
当PDE里面的标志位PS位为1的时候,该PDE指向的物理页是大页,35-21位是大页的物理地址,这样36位的物理地址的低21位为0,这就意味着页的大小为2MB,且都是2MB对齐。
(PS=0)
2-9-9-12的9位,它是PDE,这个每项占8个字节,如下图所示
当PS=0时,第35-12位是页表基址,低12位补0,共36位。
P (Present) (第0位):
- 指示该PDE是否有效。1表示有效,0表示无效。
RW (Read/Write) (第1位):
- 指示页面是否可写。0表示只读,1表示可读写。
US (User/Supervisor) (第2位):
- 控制访问权限。0表示内核模式,1表示用户模式。
PWT (Page-level Write-Through) (第3位):
- 控制缓存写通策略。
PCD (Page-level Cache Disable) (第4位):
- 控制是否禁用缓存。
A (Accessed) (第5位):
- 标记该页是否被访问过。
0 (第6位):
- 保留位,必须为0。
PS (Page Size) (第7位):
- 指示页的大小。0表示4 KB页,1表示2 MB页(PAE模式下不使用4 MB页)。
G (Global) (第8位):
- 标记全局页。当启用CR4中的PGE位时,全局页在上下文切换时不会刷新TLB。
0 (第9位):
- 保留位,必须为0。
Reserved (第10-11位):
- 保留位,必须为0。
Base Address (第12-35位):
- 页表的物理基地址,指向下一级的页表(对于4 KB页)
Reserved(set to 0,第36-63位):
- 保留位,给下一代cpu
PTE
2-9-9-12的9位,它是PTE,这个每项占8个字节,如下图所示
PTE中第35-12是物理页基址,24位,低12位补0物理页基址+12位的页内偏移指向具体数据
PAT用于指定页面的缓存属性的。它与页属性表(Page Attribute Table)一起工作,允许操作系统指定不同的缓存策略以优化内存访问。
PDPTE(Page-Directory-Point-Table-Entry):
2-9-9-12最高的2位,它是页目录指针表项,这个每项占8个字节,如下图所示
P (Present) (第0位):
- 表示页目录指针表项是否有效。1表示有效,0表示无效。
RW (Read/Write) (第1位):
- 指示指向的页是否可写。0表示只读,1表示可读写。
US (User/Supervisor) (第2位):
- 控制访问权限。0表示内核模式,1表示用户模式。
PWT (Page-level Write-Through) (第3位):
- 控制缓存写通策略。
PCD (Page-level Cache Disable) (第4位):
- 控制是否禁用缓存。
保留位 (第5-8位):
- 通常设置为0,不被使用。
Reserved (第9-11位):
- 保留位,通常为0。
Page-Directory Base Address (第12-35位):
- 指向页目录的物理地址
Reserved(set to 0):
- 通常设置为0,不被使用
整体的2-9-9-12架构
先查页目录指针表确定是哪一个页目录表项,占两位,有2^2=4种可能
然后查询页目录表找到页表,由2^9=512种可能
然后查询页表项,有2^9=512种可能
所以总共能映射的内存是4 * 512 * 512* 4k = 4M(一个分页为4K)
如果一个分页大小是4M,那么就没有页表了
逻辑地址转物理地址实战
因为分段机制已经没啥用了,所以 逻辑地址 = 线性地址
现在我们来转换一下0x11A2014这个地址
0x11A2014拆成二进制为:00 000001000 110100010 000000010100
页目录指针index 0
页目录index 0x8
页表index 0x1A2
偏移 0x14
根据页目录指针找到页目录表基地址,加下标得到页目录表项地址:
1 | 1: kd> !dq cr3+0*8 |
分解一下,页目录表的基地址为0x167dc000,属性为0x801,最低位为1,所以是有物理内存映射的
页目录表项地址为0x167dc000 + 0x8*8
根据页目录表项找到页表基地址,加下标得到页表项
1 | 1: kd> !dq 0x167dc000 + 0x8*8 |
分解一下,得到页表基地址为0x3c765000(如果有页表),属性为0x867,查看属性,重点看第0位和第7位,说明物理地址有效并且分页大小为4K,说明有页表
所以页表项地址为0x3c765000+0x1A2*8
根据页表项找到页框物理基地址,加偏移得到物理地址
1 | 1: kd> !dq 0x3c765000+0x1A2*8 |
页框物理基地址为0x2df5000
最终物理地址为0x2df5000+0x14=0x2df5014
发现最终也是成功对上了