[转]解析Winndows 2000/XP物理内存管理

物理内存是相对比较紧张的资源,合理利用将是一个操作系统的性能的关键。Windows 2000/XP内部使用一个称为页框数据库(Page Frame Database)的结构用于描述物理内存的状态。本文将从这一结构入手详述Windows物理内存的组织与管理。

Windows将物理内存按PAGE_SIZE(在x86上,为0x1000字节,即4K)为单位,将其划分,每一单元在页框数据库中均有一项描述其状态及用途等。页框数据库实际上是由这些描述每一页情况结构的数组。页框数据库由内核变量MmPfnDatabase指定,而数据库中的项数则由MmNumberOfPhysicalPages指定,项数索引叫Page Frame Number(PFN)来表示。MmNumberOfPhysicalPages通常略低于系统实际拥有的物理内存页数,系统在初始化阶段保留部分页面让操作系统本身使用。需要指出的是页框数据库只描述狭义上的物理内存,不包含其他映射的物理设备的内存。

Windbg的!pfn命令用于对任一页内存的状态及用途等进行分析,如下所示:

kd> dd MmPfnDatabase l 1
    80547438  80c00000
    kd> !pfn 143
        PFN 00000143 at address 80C01E48
        flink       00000500  blink / share count 00000001  pteaddress E1085174
        reference count 0001   Cached     color 0
        restore pte 00B5AC24  containing page        0096D8  Active      P      
          Shared

  《Inside Windows 2000》中将PFN的各个字段解释的已经非常清楚了。这里我只是简要进行说明:

  flink与blink用于将特定状态的页面连成一个链表,系统中内核变量MmZeroedPageListHead、MmFreePageListHead、MmStandbyPageListHead、MmModifiedPageListHead、MmModifiedNoWritePageListHead、MmBadPageListHead用于指示这些状态的页面的链表头。从这些变量名很容易明白各链表的页面状态,在Windows中页框数据库中共有8个状态,另两个为:Active与Transition状态。这8个状态由pfn的type(offset:0xd,size:byte)字段中的前3bit指示。

  pteaddress是指向这一页面的pte地址。经过分析,主要有如下三种情况:

a. pteaddress为0或0xffffffff,根据pfn指示的状态,可识别是ZeroedPage或是FreePage。
    b. pteaddress为0xC*******,表明这一页面当前有系统或某一进程独占,并且在进程或系统工作集中。
  c. pteaddress为0xE*******,说明这是一个prototype pte,也就是说这个页面是共享的。详细请参阅我的《探究Windows 2000/XP原型PTE》。

  restore pte,在《Inside Windows 2000》中称为original pte。其作用是指示这一页面的back-store位置,即数据在磁盘中某一pagefile或是mapped file中的位置。譬如在上面提及的情况c中,其一般是指向mapped file的某一subsection,所以在内部其称为Subsection PTE,由MMPTE_SUBSECTION结构定义。而另外一种情况其可能是一个指向pagefile的pte,由MMPTE_SOFTWARE结构定义。这一点,上次我提及时存在错误。MMPTE_SUBSECTION的具体bit定义如下:

Valid            : Pos 0, 1 Bit
    SubsectionAddressLow : Pos 1, 4 Bits
    Protection       : Pos 5, 5 Bits
    Prototype        : Pos 10, 1 Bit
    SubsectionAddressHigh : Pos 11, 20 Bits
    WhichPool        : Pos 31, 1 Bit

  最高位WhichPool是指示这个Subsection位于哪个pool中(NonPagedPool或是PagedPool中),Valid为0,指示这不是一个x86硬件可以识别的pte,由MiDispatchFault分析。由Subsection pte转换成Subsection地址的算法我在底下提供的代码中给出了。

这一描述基本阐述了Subsection PTE的作用,用于定位由PFN所指定的页面位于相应的Mapped File的位置。为了更好的解释好这一过程,《Inside Windows 2000》中使用了一个框图来解释内存管理器内部的这几个千丝万缕的联系,但各个数据结构,如PFN,SEGMENT等等介绍的不够详尽,并且之间的转换算法均没有提及。下图是我根据Windows XP Professional Build 2600的情况,重新制作的一幅图.

Windbg提供了一个!memusage命令通过分析subsectin pte得到系统中各个mapped file的使用内存情况,底下的代码,只是详细的列出了某些页面由哪些mapped file使用,并没有像!memusage有详细的统计功能,不过通过这一代码与我先前提供的文章,也能基本上明白上面这幅图之间复杂关系。

 1     /*
 2        For test purpose,I define the below constant,but no say
 3        MmSubsectionBase and MmNonPagedPoolEnd are fixed in
 4        Windows 2000 and Windows XP. They are initialized on system
 5        boot phase by ntoskrnl and rely on the system physical memory size etc.
 6     */
 7     #define WIN2000_2195
 8     #ifdef WINXP_2600
 9     #define MmSubsectionBase 0x80d21000
10     #define MmNonPagedPoolEnd 0xffbe0000
11     #endif
12     #ifdef WIN2000_2195
13     #define MmSubsectionBase 0x0
14     #define MmNonPagedPoolEnd 0xffb7f000
15     #endif
16
17     #define MmPfnDatabase 0xffb7f000    //Please redefine it on your machine.
18     #define MmNumberOfPhysicalPages 0x3f7d  //Please redefine it on your machine.
19
20     /*
21       Portion of nt!MiGetSubsectionAndProtoFromPte
22       Get Subsection from restore pte(original pte) at PFN Database Entry
23       disasm by WebCrazy([email protected]) athttp://webcrazy.yeah.net
24      Thanks to wuzq([email protected]) for light!
25     */
26
27     unsigned int MiGetSubsectionAndProtoFromPte(int pte)
28     {
29        unsigned int subaddr;
30        if(pte < 0){
31           subaddr = MmSubsectionBase+(((pte & 0x1e) <<2) |  ((pte>>4) & 0x7ffff80)) ;
32        }else{
33           subaddr = MmNonPagedPoolEnd-(((pte & 0x1e) <<2) |  ((pte>>4) & 0xfffff80)) ;
34        }
35        return subaddr;
36     }
37
38     /*
39       I release memusage() to dump Control Area.
40       Only mapped file control area were dump.
41       Please see windbg !memusage command.
42     */
43
44
45     void memusage()
46     {
47          unsigned int *pfndatabase = MmPfnDatabase;
48          unsigned int numberphys = MmNumberOfPhysicalPages;
49
50          unsigned int restorepte,pfn=0,ppte,subsection;
51
52          unsigned char flag=0;
53          static unsigned int flagnum[8];
54          static char *flagdesc[8]=
55                 {"Zeroed","Free","Standby","Modified","ModNoWrt","Bad","Active","Trans"};
56          memset(flagnum,0,sizeof(flagnum));
57
58          for(;pfn<numberphys;pfn++){
59             flag = *(char *)((char *)pfndatabase+0xd);
60             flag &= 0x07;
61             flagnum[flag]++;
62             pfndatabase+=0x18/0x04;
63         }
64
65         DbgPrint("\nMemUsage:\n");
66         for(flag=0;flag<8;flag++)
67              DbgPrint("%10s:%04d(%08dK)\n",flagdesc[flag],flagnum[flag],flagnum[flag]*4);
68
69
70         pfndatabase = MmPfnDatabase;
71         for(pfn=0;pfn<numberphys;pfn++){
72             ppte=*((unsigned int *)(pfndatabase+0x1));
73             restorepte=*((unsigned int *)(pfndatabase+0x4));
74             flag = *(char *)((char *)pfndatabase+0xd);
75             flag &= 0x07;
76
77             if(ppte>=0xE1000000&&ppte<0xF0000000){
78                subsection=MiGetSubsectionAndProtoFromPte(restorepte);
79                DbgPrint("pfn:%04X,ppte:%08X,restorepte:%08X,subsection:%08X,ca:%08X,
80                     flag:%10s\n",pfn,ppte,restorepte,subsection,
81                     MmIsAddressValid((void *)subsection)?*(unsigned int *)subsection:
82                     0x11111111,flagdesc[flag]);
83             }
84             pfndatabase+=0x18/0x04;
85         }
86     }
时间: 2024-11-08 04:48:40

[转]解析Winndows 2000/XP物理内存管理的相关文章

java微信开发API解析(五)-用户管理

java微信开发API解析(五)-用户管理 全局说明 * 详细说明请参考前两篇文章. 本文说明 *本文分为五部分: * 工具类MyHttpUtils的封装 * 用户分组管理文档的简单阅读解析 * 分组bean的构建以及各种分组管理的实现源码 * 用户管理的应用场景 * 测试的微信号二维码 * 本文只分析用户管理的用户分组管理部分,其它都大同小异,不再分析处理.如需要,请留言. * 以后原理分析会越来越简洁,具体原理分析请查看以前文章. * 下一篇文章会对于用户普通消息.自定义菜单消息.自动完成用

Windows CSRSS API List (NT/2000/XP/2003/Vista/2008/7/2012/8)

原文地址:http://j00ru.vexillium.org/csrss_list/api_list.html http://j00ru.vexillium.org/csrss_list/api_table.html 博客园显示不完整,图片下载:http://files.cnblogs.com/files/luzhiyuan/2015-03-06.rar 说明:其中绿色为有效 Windows CSRSS API List (NT/2000/XP/2003/Vista/2008/7/2012/8

防止入侵 两步修改XP远程管理默认端口

自Windows 2000开始,微软就提供一项终端服务(Terminal Server)这项服务可以将远程的桌面传递到本地.通过该服务,可视化的远程管理可以非常方便的实现.继Windows 2000之后,Windows XP也提供这项服务.在Windows XP 中的Terminal Server Client程序比Windows 2000中的那个有了进一步的发展,许多功能都强大了许多. Windows XP 中的Terminal Server Client程序主要的新特性有: 1)可以将目标机

linux物理内存管理

1.为什么需要连续的物理内存: Linux内核管理物理内存是通过分页机制实现的,它将整个内存划分成无数个4k(在i386体系结构中)大小的页,从而分配和回收内存的基本单位便是内存页了.利用分页管理有助于灵活分配内存地址,因为分配时不必要求必须有大块的连续内存[3],系统可以东一页.西一页的凑出所需要的内存供进程使用.虽然如此,但是实际上系统使用内存时还是倾向于分配连续的内存块,因为分配连续内存时,页表不需要更改,因此能降低TLB的刷新率(频繁刷新会在很大程度上降低访问速度). 1.物理内存页和p

windows 2000/xp WDM设备驱动程序开发 (1)

0. 参考文献 <windows WDM 设备驱动程序开发指南><programming the microsoft windows driver model> <windows 2000驱动程序开发大全> 使用driverworks工具(driverStudio),而没有用DDK,因为更快捷 1. WDM驱动 例程 页故障:软件级别中断,运行在DISPATCH_LEVEL上: 所以访问DISPATCH_LEVEL的代码需运行在非分页内存 1.3 设备接口 旧的命名方法

f2fs解析(七)node管理器中的 free_nid 结构体

除了node_info之外, node管理器中还有还有个重要的数据结构: 145 struct free_nid { 146 struct list_head list; /* for free node id list */ 147 nid_t nid; /* node id */ 148 int state; /* in use or not: NID_NEW or NID_ALLOC */ 149 }; 这个结构体体很简单,比刚才的node_info轻量级多了,仅仅是标识了当前可以使用的n

[Windows系统安装]PE/2000/XP/2003/Vista/2008/7/8/8.1Pre版本

近日,Windows 8.1 RTM 正式版已经泄漏在网上,其与十月将发布的MSDN 正式版不会有任何区别,推荐喜欢Windows 8的朋友下载安装,下载地址: 详见此文,下面将分享Windows 8.1的安装与激活教程,以方便大家安装激活Win 8.1. 一,Windows 8.1 安装教程 在安装过程中,需要输入Windows 8.1 密钥才能完成安装,根据需要安装的版本选择密钥进行安装. 注意此密钥只能安装,不能用来激活,若需要激活,建议从淘宝购买正版Windows 8.1 序列号,详情点

windows 2000/xp WDM设备驱动程序开发 (2)

4. WDM环境 a  安装VC6.0: b  安装相应操作系统的DDK(组件一定要全选): c  安装DriverStudio: d  用VC6.0打开Compuware\Driver Studio\DriverWorks\Source\VdwLibs.dsw工程: 1)用DriverStudio的driverWizard来创建工程 创建RegSample完后编译出现错误,删掉没有的函数,然后去掉了ntstrsafe.lib 链接库 2)EzDriverInstaller (driverstu

物理内存管理

物理地址空间:硬件支持的地址空间. 逻辑地址空间:在CPU运行的进程看到的地址. 一.连续内存分配: 1.匹配策略: 最先匹配策略:空闲分区列表按地址顺序排序,遇到第一个大于所需空间的空闲分区就分配. 最佳匹配策略:  空闲分区列表按从小到大排序,遇到第一个大于所需空间的空闲分区就分配(即大于所需空间的空闲分区中 空间最小的一个分区). 最差匹配策略:空闲分区列表按从大到小排序,分配第一个空闲分区(即最大的空闲分区).第一个都小于所需空间的话,则没有空间分配. 2.碎片整理: 紧凑:应用程序可动