windows的页自映射机制
windows下由于启用了页机制,所有软件层面的地址操作都是VA,通过descriptor(base address(32bit))+offset得到的线性地址并不直接对应物理地址,而是经过页转换机构再做一次转换得到物理地址,这样的转换是硬件提供的能力,转换过程被说的比较多了,大体是通过cr3寄存器得到page direcotry的物理地址,Vitrual Address的高10位就是一个(pde)page direcotry entry的index,或许可以像这样表示cr3[VA>>22],一个pde又指向了一个page table,VA接下来的10bit就是page table中的一个索引,即一条pte(page talbe entry),pte中存放了page的地址,低12位就是在前述转换过程中得到的page中的offset。
需要特别说明的是,pde and pte中存放的是物理帧号(physical frame number)位于pde or pte的高20bit,也就是说可以表示1M个物理帧,每个物理帧大小是4kb,这样就可以表示4GB的内存。
说了半天还没到自映射机制,前面说的都是硬件提供的能力,只要是拿到一个VA硬件层面都进行相同的转换步骤,windows要做内存管理,就需要维护page directory和 page tables,如何通过一个VA得到它所在的页的VA以及所在的页表的VA呢?
微软提供了下面几个宏处理给定的VA
#define MiGetPdeAddress(VA) ((PMMPTE)(((((ULONG)(VA)) >> 22) << 2) + PDE_BASE))//此处PDE_BASE为0xc0300000(这也是一个VA,经页转换后得到的是PD的起始地址,下面就是所谓的自映射了,页转换机构利用VA的高十位(0x300)索引到一个PDE,这个PDE的特别之处是并没有指向一个page table而是指向了page directory的起始地址,一个PD占据一页,一个PT也占据一页),继续把page directory作为一个page table,再用VA的中间10位(还是0x300)又索引到了page directory的起始位置,低12位是0,即offset为0,最终得到的就是Page Directory的起始地址。那么VA先右移22,再左移2(相当于乘以4)加上PDE_BASE经过得到一个VA,经过两次自映射,加上offset后,得到的物理地址就是PDE的物理地址。
#define MiGetPteAddress(va) ((PMMPTE)(((((ULONG)(va)) >> 12) << 2) + PTE_BASE))
这里的PTE_BASE是一个常量,为0xC0000000,也就是说page directory entry的索引(0x300)仍然索引到page directory的起始位置,和上面的宏一样,又是一次自映射。
#define MiGetVirtualAddressMappedByPte(PTE) ((PVOID)((ULONG)(PTE) << 10))//如果是给了一个VA,想要得到所在page的起始地址,只需将VA的低12位清零就可以得到VA所在页的VA,但这里给的是PTE(相当于(*PDE)),因为pte的高十位总是指向PD的起始位置,左移10位之后就相当于取消了这次自映射,当然这里的转换只对利用自映射的va有效。
再说一下,exe载入内存的时候,如何建立描述符,首先根据image的大小分配若干页的内存,这里假设image 在内存中占80kb,基址是0x00400000h,系统共分配20页的内存,起始页的VA假设是1110010000|1101110000|000000000000b(pde index(0x390):pte index(0x370):offset(0x0)),则descriptor.base+00400000h=E4370000h->descriptor.base=E3F70000h,那么code段描述符中的基址就可以根据其相对于00400000h的偏移加上E4370000h得到,比如code段的va是00401000h,那么他的描述符中的基址为E3F71000h,正好是从内存中image的第2页开始。更进一步,将新建code段描述符在GDT中的index(选择子)载入到cs,程序就可以运行了。
总起来说,硬件的转换机制并没有改变,只是windows利用硬件提供的这种能力使自己能方便的维护PD和PT
经过后来的相关资料的学习,PDE_BASE这个值是一个线性地址,微软通过一个宏来指定他的值,而CR3总的值一定是物理地址,并且在切换进程的时候这个值是会改变的
另外描述符实际上是对PE中的VA进行了一层包装
VA:vitual address
PTE:page table entry
PDE:page directory entry
PD:page directory
PT:page table
windows的页自映射机制的更多相关文章
- x86平台上的Windows页表映射机制
首先,在x86架构的处理器上,一个正常页面大小为4KB,非PAE模式下,CR3持有页目录页面的物理地址,PDE和PTE格式相同大小为4字节.此时每个页表页面包含1024个PTE,可以映射1024个页面 ...
- 深入解析Windows操作系统笔记——CH3系统机制
3.系统机制 微软提供了一些基本组件让内核模式的组件使用: 1.陷阱分发,包括终端,延迟的过程调用(DPC),异步过程调用(APC),异常分发以及系统服务分发 2.执行体对象管理器 3.同步,包括自旋 ...
- linux 逆向映射机制浅析
2017-05-20 聚会回来一如既往的看了会羽毛球比赛,然后想到前几天和朋友讨论的逆向映射的问题,还是简要总结下,免得以后再忘记了!可是当我添加时间……这就有点尴尬了……520还在写技术博客…… 闲 ...
- 操作系统学习笔记(二) 页式映射及windbg验证方式
页式映射 本系列截图来自网络搜索及以下基本书籍: <Windows内核设计思想> <Windows内核情景分析> <WINDOWS内核原理与实现> 一个32位虚拟地 ...
- Windows内核开发-6-内核机制 Kernel Mechanisms
Windows内核开发-6-内核机制 Kernel Mechanisms 一部分Windows的内核机制对于驱动开发很有帮助,还有一部分对于内核理解和调试也很有帮助. Interrupt Reques ...
- MFC编程入门之五(MFC消息映射机制概述)
在MFC软件开发中,界面操作或者线程之间通信都会经常用到消息,通过对消息的处理实现相应的操作.比较典型的过程是,用户操作窗口,然后有消息产生,送给窗口的消息处理函数处理,对用户的操作做出响应. 一.什 ...
- VS2010/MFC编程入门之五(MFC消息映射机制概述)
VS2010/MFC编程入门之五(MFC消息映射机制概述)-软件开发-鸡啄米 http://www.jizhuomi.com/software/147.html 上一讲鸡啄米为大家简单分析了MFC应用 ...
- MFC消息映射机制
1.MFC应用框架主要类之间的关系 MFC自动生成的框架中重要的类有:C-App.CMainFrame.C-Doc和C-View. 其他的类如CClassView.CFileView等都是在框架窗口( ...
- MFC的消息映射机制揭秘
MFC的设计者们在设计MFC时,紧紧把握一个目标,那就是尽可能使得MFC的代码要小,速度尽可能快.为了这个目标,他们使用了许多技巧,其中很多技巧体现在宏的运用上,实现MFC的消息映射的机制就是其中之一 ...
随机推荐
- linux下的deb/rpm文件的说明和安装方法
1. deb 是 ubuntu .debian 的格式. rpm 是 redhat .fedora .suse 的格式. 他们不通用(虽然可以转换一下). deb是debian发行版的软件 ...
- fragment的一些bug
自从Android3.0引入了Fragment之后,使用Activity去嵌套一些Fragment的做法也变得更加流行,这确实是 Fragment带来的一些优点,比如说:Fragment可以使你能够将 ...
- META标签的NAME变量
META标签的NAME变量语法格式是: <META NAME=xxx CONTENT=xxxxxxxxxxxxxxxxxx> 其中xxx主要有下面几种参数: 1. Keywords(关键字 ...
- Android绘图之渐隐动画
实现了一个有趣的小东西:使用自定义View绘图,一边画线,画出的线条渐渐变淡,直到消失.效果如下图所示: 用属性动画或者渐变填充(Shader)可以做到一笔一笔的变化,但要想一笔渐变(手指不抬起边画边 ...
- GridView 分页方法
要实现GrdView分页的功能. 操作如下: 1.更改GrdView控件的AllowPaging属性为true. 2.更改GrdView控件的PageSize属性为 任意数值(默认为10) 3.更改G ...
- mysql 远程连接失败(linux)
主要有三个原因:1.mysql授权表里没有远程机器的权限,及需要在授权表mysql.user添加grant all privileges on *.* to 'root'@'远程登陆IP' ident ...
- magento二次开发的基本步骤分享
Magento后台添加新模块的体会 确定命名空间(Namespace)和模块(Modulename)的命名: 在app/etc/modules/ 路径下,创建 Namespace_Modulename ...
- cmake在实际复杂项目中的使用
在实际复杂的项目之中,会有很多的源文件,以及对于库的依赖,如果直接使用makefile会比较的繁琐,而且makefile的推导规则也非常多,对多目录的支持也比较复杂. 最近看了一下cmake,发现配置 ...
- 【Bear】api分类
参考 jQuery API 中文文档
- Hashing filters for very fast massive filtering
If you have a need for thousands of rules, for example if you have a lot of clients or computers, al ...