文章目录
-
- 非PAE 非物理地址扩展
-
- 线性地址 有效地址 物理地址
- CR3
- PDE/PTE
- 物理页的属性
- 通过线性地址访问PDT和PTT
-
- 指向PDT的线性地址 0xC0300000
-
- 总结
- 指向PTT的线性地址 0xC0000000/C0001000
-
- 总结
- 访问PDT与PTT公式总结
非PAE 非物理地址扩展
线性地址 有效地址 物理地址
如下指令:
mov eax,dword ptr ds:[0x12345678]
这个地址如果想访问成功,首先取决于段机制,看当前的环境能否通过段权限检查以及是否超过limit限制等等。其次,取决于页机制。
- 其中,0x12345678是有效地址
- ds.base+0x12345678是线性地址
- 线性地址也不是真正的地址,还有一个地址被称为物理地址
CPU会通过这个线性地址作为一个目录,去索引物理地址。问题在于A进程有一个地址0x12345678,B进程也有一个地址0x12345678。那么CPU通过什么去分别找到这两个相同内存地址的不同的物理地址呢?答案是页目录基址。
CR3
每个进程都有一个CR3寄存器,保存页目录基址。这个基址是物理地址。CR3指向一个物理页,一共4096字节,如图:
PDE/PTE
- CR3寄存器保存的物理地址指向页目录表PDT,里面的每一个成员叫PDE。页目录表大小为4KB,每个成员为4个字节。
- 每一个PDE又指向页表PTT,里面的每一个成员叫PTE。页表大小为4KB,每个成员为4个字节。
- 每一个PTE都指向物理页,每个物理页大小为4096个字节
- PDE与PTE都是4个字节(32位),前20位是物理地址,后12位是属性
- PTE可以没有物理页,也可以指向物理页,但只能对应一个物理页
- 多个PTE可以指向同一个物理页
- 每一个线性地址都会经过一个PDE和PTE最终指向一个物理页,这个物理页能不能读写取决于经过的PDT和PTE的后12位
物理页的属性
- 物理页的属性由PDE和PTE共同决定
- P:是否有效
- R/W:是否可读可写,0代表只读,1代表可读可写
- U/S:U/S=0 物理页只允许特权用户访问;U/S=1 物理页普通用户也能访问。高2G以上的内存只有内核才能访问的原因是U/S位设置的问题,如果将内核的某个页设置为1,就可以在R3进行访问了
- A:是否被访问过,访问过设置为1。即使只访问一个字节也会导致PDE和PTE置1
- D:是否被写过;0没有被写过,1被写过
- PS:只对PDE有意义,
PS==PageSize
的意思。当PS==1
的时候PDE直接指向物理页,无PTE,低22位是页内偏移。此时,线性地址只能拆成两段:大小为4MB,俗称大页 - 9-11位:当P位为0时,CPU会产生缺页异常,此时这两位标识了该线性地址是否有效,也标识了该线性地址对应的物理内存所在
通过线性地址访问PDT和PTT
指向PDT的线性地址 0xC0300000
现在问题来了,如果我们想访问0这个地址,那么就必须找到PDT和PTT,而CR3里面保存的PDT是物理地址,提供给CPU使用的,代码只能访问线性地址。
如何解决这个问题呢?有一个线性地址,指向的是PDT,这个地址就是0xC0300000,下面对这个地址进行拆分
0xC0300000
#二进制为:
1100 0000 0011 0000 0000 0000 0000 0000
#拆成10:10:12
1100 0000 00------>0x300*4=C00
11 0000 0000------>0x300*4=C00
0000 0000 0000
将这个线性地址拆分之后,找到的对应的物理页就是CR3保存的页目录PDT基址所在的物理页。那就意味着我们可以直接通过这个线性地址去修改PDT。
**结论:**C0300000存储的值就是PDT,如果我们要访问第N个PDE,那么有如下公式:
0xC0300000+N*4
总结
- 通过0xC0300000找到的物理页就是页目录表
- 这个物理页既是页目录表本身也是页表
- 页目录表是一张特殊的页表,每一项PTE指向的不是普通的物理页,而是指向其他的页表
指向PTT的线性地址 0xC0000000/C0001000
也就是说通过0xC0300000这个线性地址可以任意修改页目录表,但如果我们要设置某个线性地址PDE和PTE那么还要能够访问PTT,如何访问呢?
答案是通过这两个线性地址:0xC0000000/C0001000。
通过拆分可以知道,访问0xC0000000这个地址就等于是访问第一个PTT表;访问C0001000这个地址就等于是访问第二个PTT表。两个地址之间相差0x1000。如果想访问第三个PTT表的话以此类推。
总结
- 页表被映射到了从0xC0000000到0xC03FFFFF的4M空间
- 在这1024个表中有一张特殊的表:页目录表
- 页目录表被映射到了0xC0300000开始处的4K地址空间
访问PDT与PTT公式总结
PDI:页目录表索引
PTI:页表索引
访问页目录表的公式:0xC0300000+PDI*4
访问页表的公式:0xC0000000+PDI*4096+PTI*4
与PTT公式总结
PDI:页目录表索引
PTI:页表索引
访问页目录表的公式:0xC0300000+PDI*4
访问页表的公式:0xC0000000+PDI*4096+PTI*4