在Windows的虚拟内存管理方案中,有一个设计值得特别一提,那就是Windows页目录自映射机制。Dave Probert很早在一份讲义中提到了这一机制(称为self-mapping page tables),并且给出了清楚的解释(http://i-web.i.u-tokyo.ac.jp/edu/training/ss/msprojects/data/07-ProcessesThreadsVM.pdf,2004年7月)。

首先,看下面的一个宏:

#define MiGetVirtualAddressMappedByPte(PTE) ((PVOID)((ULONG)(PTE) << 10))

此宏的含义是,给定一个PTE的虚拟地址,返回该PTE所指页面的虚拟地址。

举例而言,假设PTE的地址(虚拟地址)为0xc0390c84,即1100,0000,00|11,1001,0000,|1100,1000,0100,这里“|”符号将它分为页目录索引、页表索引、页内偏移三部分。在Windows中,页目录(CR3寄存器)的地址是0xc0300000,所以,处理器在访问该PTE的时候,首先从页目录页面中,找到1100,0000,00项,即第0x300项。这一项由系统特别设置好,它指向页目录自身(后面进一步解释为什么这么设置)。接下来查找0xc0390c84的页表索引,即11,1001,0000,处理器继续在页目录页面中查找,找到11,1001,0000,即第0x390项,这一项指向一个页表页面。最后,处理器再根据页内偏移1100,1000,0100,即0xc84,定位到第0x321项。此PTE的寻址过程如下图所示。

图解说明:0x300是页目录中的偏移,通过这个偏移值得到一个目录项(PDE Page Directory Entry),通过这个目录项里的值得到了一个页表的基地址,其中0x390是页表中的偏移,通过这个偏移得到了一个页表项(PTE PageTable Entry),页表项里的值也就是我们要寻找的值。这里页目录的0x300偏移中的值和页目录的基地址是相同的,都是0xc0300000,这点是微软的巧妙设计,所以这里的页表的基地址也就是页目录的基地址了,从而此图中的0x390也是从PD中来查找的,相当于把PD当成PT了,之所以PD和PT能通用,是因为PDE和PTE的格式是兼容的原因。

按照MiGetVirtualAddressMappedByPte,将0xc0390c84,左移10位,变成0xe4321000,即1110,0100,00|11,0010,0001,|0000,0000,0000,这样得到页目录索引1110,0100,00,即0x390;页表索引为11,0010,0001,即0x321;页内偏移为0。可以看到,这里复用了PTE寻址过程中的两次查表步骤。此PTE所指页面的寻址过程如下图所示。

MiGetVirtualAddressMappedByPte宏之所以能够工作的关键之处在于,页目录页面(虚拟地址为0xc0300000)的0x300项指向其自身。即下图的结构。

由此可以明白,页目录地址0xc0300000和这里的0x300项绝不是偶然的,而是精心选择的(但并非唯一)。

我在阅读Windows内核中一段分配系统PTE的代码时,看到了MiGetVirtualAddressMappedByPte宏,百思不得其解。经过两个晚上的苦思冥想,才领悟到上述寻址结构的奥妙所在。后来整理成“Windows内核原理与实现”一书中关于Windows页目录自映射方案的描述(见第202-204页)。再后来,偶然的机会看到Dave Probert的讲义中早有提及,印证了自己的想法。

Windows页目录自映射方案相关推荐

  1. Windows保护模式学习笔记(八)—— 页目录表基址/页表基址

    Windows保护模式学习笔记(八)-- 页目录表基址/页表基址 要点回顾 一.页目录表基址 实验:拆分线性地址C0300000,并查看其对应的物理页 第一步:打开一个进程,获得它的Cr3 第二步:查 ...

  2. 企业的Windows活动目录规划方案集合(附学习视频)

    企业的Windows活动目录规划方案集合(附学习视频) 活动目录(Active Directory)是面向Windows Standard Server.Windows terprise Server ...

  3. [转载]Win7中的页目录

    转自:http://user.qzone.qq.com/31731705/blog/1324046552 文章 PAE下的虚拟内存映射 分析 ( http://user.qzone.qq.com/31 ...

  4. 内核知识第八讲,PDE,PTE,页目录表,页表的内存管理

    内核知识第八讲,PDE,PTE,页目录表,页表的内存管理 一丶查看GDT表. 我们通过WinDbg + 虚拟机可以进行双机调试.调试一下看下GDT表 我们知道,GDT表中.存储的是存储段信息. 保存了 ...

  5. (21)页目录表,页表基址(XP系统 10-10-12分页模式)

    一.页目录表PDT 0xc0300000 指向页目录表(PDT) 0xc0000000 指向第一张页表(PTT) 页目录表其实是一张特殊的页表,它是第0x300张页表. 页目录表中每项PTE都指向一张 ...

  6. 页目录项和页表项——《x86汇编语言:从实模式到保护模式》读书笔记43

    页目录项和页表项 上图就是页目录项和页表项的格式.可以看出,由于页表或者页的物理地址都是4KB对齐的(低12位全是零),所以上图中只保留了物理基地址的高20位(bit[31:12]).低12位可以安排 ...

  7. 【OS学习笔记】三十一 保护模式九:页目录、页表和页三者的关系详解

    上一篇文章学习了:保护模式九:段页式内存管理机制概述 本篇文章接着学习以下内容: 页目录概念 页表概念 页目录.页表与页之间的关系 虚拟地址(线性地址)到物理地址的具体变换过程. 1.页目录.页表和页 ...

  8. Linux 匿名页的反向映射

    我们知道LINUX的内存管理系统中有"反向映射"这一说,目的是为了快速去查找出一个特定的物理页在哪些进程中被映射到了什么地址,这样如果我们想把这一页换出(SWAP),或是迁移(Mi ...

  9. 页目录和页表结构---醍醐灌顶

    http://blog.sina.com.cn/s/blog_533074eb0101ai5t.html 上图反映了如下信息: 1. 进程的 4G 线性空间 被划分成 三个部分 : 进程空间 (0-3 ...

最新文章

  1. DWS和各异构数据库的差异对比
  2. Modesim 仿真 ERRO VSIM-19
  3. ios wkweb设置图片_iOS wkwebview和 uiwebview 内容图片自适应大小
  4. go语言接收html传值,Go语言参数传递是传值还是传引用
  5. Foxconn Core Concept
  6. SVN: repository browser 库浏览器
  7. python kmeans聚类_K-means聚类算法的Python实现
  8. 管理感悟:软件公司不加班还搞什么软件
  9. 小程序直播 OBS 画质_教你玩转微信小程序直播
  10. jstree取消勾选_zTree 节点勾选取消勾选 选中取消选中
  11. python程序设计pdf机械出版_Python程序设计
  12. ecg 幅度_心电图(ECG或EKG)设计原理及实例应用
  13. rgb sw 线主板接口在哪_配置升级性能再突破,华硕TUF GAMING B460M-PRO 重炮手主板爆款来袭...
  14. related_name/related_query_name的区别
  15. 《数字图像处理》-(3)-1从傅里叶级数到傅里叶变换详细推导以及傅里叶图像的性质
  16. android 批量安装apk,如何一键批量安装APP应用apk安装包?
  17. 主流RGB灯,灯带通用C语言程序
  18. 营销物料(内容)可复用,别忽视了这个神器的作用!
  19. (翻译)测试替身— Fakes, Mocks 和 Stubs
  20. move_base学习(一)之双激光差动式移动机器人导航仿真

热门文章

  1. 【原创】 PostgreSQL 实现MySQL 的auto_increment 字段
  2. mysql-自动备份数据库服务
  3. mysql字符串操作
  4. 【300】◀▶ IDL - ENVI API
  5. Linux的ELF格式分析
  6. mysql 配置路径
  7. javascript简单的四则运算
  8. js插件类库组织与管理
  9. 2018年Github最受欢迎机器学习语言Python稳坐冠军,numpy、scipy是最受欢迎软件包...
  10. get_k_data 接口文档 全新的免费行情数据接口