⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jiurl玩玩win2k内存篇 page frame number database.htm

📁 关于win2000核心编程的文章
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0074)http://jiurl.cosoft.org.cn/jiurl/document/JiurlPlayWin2k/MmPfnDataBase.htm -->
<HTML><HEAD><TITLE>JIURL玩玩Win2k内存篇 Page Frame Number Database</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<STYLE type=text/css>.title {
	FONT-FAMILY: "黑体", Arial, sans-serif; FONT-SIZE: 21px; FONT-WEIGHT: bold; LINE-HEIGHT: 48px; TEXT-DECORATION: none
}
.author {
	FONT-FAMILY: "宋体"; FONT-SIZE: 12px; LINE-HEIGHT: 16px
}
.content {
	FONT-SIZE: 14px; LINE-HEIGHT: 20px
}
</STYLE>

<META content="MSHTML 5.00.2614.3500" name=GENERATOR></HEAD>
<BODY bgColor=#f7f7f7 topMargin=5>
<DIV align=center>
<CENTER>
<TABLE border=0 cellPadding=0 cellSpacing=0 height=29 width="96%">
  <TBODY>
  <TR>
    <TD class=title height=41 width="100%">
      <P align=center><FONT face=宋体>JIURL玩玩Win2k内存篇 </FONT><FONT face=宋体>Page 
      Frame Number Database</FONT></P></TD></TR></CENTER>
  <TR>
    <TD class=author height=9 width="100%">
      <P align=center><FONT face=宋体>作者: <A 
      href="mailto:jiurl@mail.china.com">JIURL</A> </FONT></P></TD></TR>
  <TR>
    <TD class=author height=6 width="100%">
      <P align=center><FONT 
      face=宋体>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      主页: <A href="http://jiurl.yeah.net/">http://jiurl.yeah.net/</A> 
    </FONT></P></TD></TR>
  <TR>
    <TD class=author height=2 width="100%">
      <P align=center><FONT face=宋体>&nbsp;&nbsp;&nbsp; 日期: 2003-7-30</FONT> 
    </P></TD></TR></TBODY></TABLE></DIV>
<DIV align=center>
<CENTER>
<TABLE border=0 cellPadding=0 cellSpacing=0 height=1 width="96%">
  <TBODY>
  <TR>
    <TD height=1 width="100%">
      <HR color=#396da5 SIZE=3>
    </TD></TR></TBODY></TABLE></CENTER></DIV>
<DIV align=center>
<TABLE border=0 cellPadding=0 cellSpacing=0 class=content height=4300 
width="96%">
  <TBODY>
  <TR>
    <TD height=2132 vAlign=top width="131%"><B>引子</B> 
      <P>&nbsp;&nbsp;&nbsp; 
      当系统需要提供一个物理页给应用程序,来满足应用程序要求的时候,将遇到一个问题,系统如何知道哪些物理页已经被使用,哪些物理页没有被使用。Page 
      Frame Number (PFN) DataBase (页帧号数据库)和它的相关结构用来解决这个问题。</P>
      <P><B>Working Set 简介</B><BR><BR>一个进程的 Working Set 
      是进程当前所使用在物理内存中的页的集合。程序使用这些页不会引发 page fault。</P>
      <P><B>页帧号数据库 ( PFN DataBase ) 概述</B></P>
      <P>&nbsp;&nbsp;&nbsp; 
      物理内存被分页,对于32位的CPU来说,每个物理页大小是4K。对于每一个物理页,系统使用一个24字节长的结构来保存它的相关信息,比如该物理页是否已经被使用。为了便于描述,我们把这个结构叫做PfnDataBaseEntry 
      ,页帧号数据库项。页帧号数据库就是一个 PfnDataBaseEntry 数组,这个数组的每一项对应一个物理页。比如 PfnDataBase 
      数组第0项,对应物理页0,也就是页帧号为0的物理页。第1项,对应物理1,也就是页帧号为1的物理页。系统把PfnDataBase的首地址保存在全局变量 
      MmPfnDatabase 中。现在我们来分析一下 
      物理页的页帧号(PFN),物理页的物理地址范围,物理页的页帧号数据库项之间的关系。对于物理页i,它的页帧号是i。由物理地址从i*0x1000到i*0x1000+0xFFF,这4KB物理内存单元组成。对应的页帧号数据库项为第i项,虚拟地址为 
      *MmPfnDatabase+i*0x18。比如在当前我所在的Win2k中,对于物理页3,它的页帧号是3,由物理地址0x3000-0x3FFF这4k的物理内存单元组成,当前我的 
      MmPfnDatabase 中的值为 0x81456000,即PfnDataBase 的首地址为 0x81456000,所以对应的 
      PfnDataBaseEntry 虚拟地址为 0x81456000 + 3*0x18 = 0x81456048。</P>
      <P>PfnDataBaseEntry 的具体内容如下</P>
      <P>struct PfnDataBaseEntry (大小24个字节,即0x18个字节)<BR>/*00*/ uint32 
      flink<BR>/*04*/ uint32 pteaddress<BR>/*08*/ uint32 blink / share 
      count<BR>/*0C*/ byte flags<BR>/*0D*/ byte page state<BR>/*0E*/ uint16 
      reference count<BR>/*10*/ uint32 restore pte<BR>/*14*/ uint32 containing 
      page<BR><BR>/*00*/ uint32 flink<BR>链上前一个 PfnDataBaseEntry 的页帧号,如果为 
      0xFFFFFFFF 表示没有前一个 PfnDataBaseEntry。<BR><BR>/*08*/ uint32 blink / share 
      count<BR>对于使用链表链在一起的物理页,表示后一个 PfnDataBaseEntry 的页帧号,如果为 0xFFFFFFFF 表示没有后一个 
      PfnDataBaseEntry。对于没有使用链表链在一起的物理页,表示共享计数。<BR><BR>/*0C*/ byte 
      flags<BR>一些标志信息。<BR><BR>/*0D*/ byte page 
      state<BR>指出物理页的状态,就是从这里判断一个物理页是否已经被使用。物理页共有8种不同的状态。<BR><BR>Active(Valid):<BR>这个物理页在某个进程的 
      Working Set 
      中,该进程的一个有效的页表项中的高20bit正是这个物理页的PFN。<BR><BR>Transition:<BR>系统正在从一个文件将内容读入该物理页,或者正在向一个文件写出该物理页内容。<BR><BR>Standby:<BR>这个物理页曾经在某个进程的 
      Working Set 中,并且物理页中的内容在被该进程使用时没有被改变过。但是现在已经被移出该进程的 Working 
      Set,不过物理页中的内容仍是在该进程 Working Set 
      中时的内容。该进程相应的PTE中的高20bit仍然是这个物理页的页帧号,只是该PTE被标为 invalid 和 
      transition。当该进程需要再次访问这一页的内容时,只需要重新设定该PTE的标志,并把该PTE变为有效。把该物理页从 Standby 
      状态变为Active(Valid) 状态就可以了。<BR><BR>Modified:<BR>这个物理页曾经在某个进程的 Working Set 
      中,并且物理页中的内容在被该进程使用时被改变过。但是现在已经被移出了该进程的 Working 
      Set,不过物理页中的内容仍是被移出时的内容。该进程相应的PTE中的高20bit仍然是这个物理页的页帧号,只是该PTE被标为 invalid 和 
      transition。当该进程需要再次访问这一页的内容时,只需要重新设定该PTE的标志,并把该PTE变为有效。把该物理页从 Modified 
      状态变为Active(Valid) 
      状态就可以了。在该物理页被系统作为其他用途使用之前,该物理页中的内容需要被写入硬盘中的交换文件的相应页。<BR><BR>Modified 
      no-write:<BR>内存管理器的 Modified Page Writer 将不会把这种物理页写入硬盘,其他和 Modified 
      物理页一样。比如,NTFS使用这个状态来保证在log之前,该页不会被写入硬盘。<BR><BR>Free:<BR>该物理页中的内容不再被需要,比如一个进程结束,这个进程所使用的一些物理页就会变为 
      Free 
      状态。(由于安全的原因,这些页需要被用零初始化,才能给一个用户进程使用)<BR><BR>Zeroed:<BR>该页free并且已经被用零初始化。<BR><BR>Bad:<BR>该页存在硬件错误,不能被使用。<BR><BR>其中 
      Zeroed,Free,Standby,Modified,ModifiedNoWrite,Bad 这6种状态的 PfnDataBaseEntry 
      使用PfnDataBaseEntry 的 flink,blink 链在该状态的 
      PfnDataBaseEntry链上。系统通过全局变量MmZeroedPageListHead,MmFreePageListHead,MmStandbyPageListHead,MmModifiedPageListHead,MmModifiedNoWritePageListHead,MmBadPageListHead 
      可以找到这6个链。这样当需要使用物理页的时候系统就可以很快的从相应的链中取出物理页。Active(Valid) 和 Transition 状态的 
      PfnDataBaseEntry 没有被任何链表链在一起,但是通过各个进程的PTE我们就可以找到,PTE的高20bit就是一个页帧号。</P>
      <P><B>页帧号数据库 ( PFN DataBase ) 分析</B><BR><BR>全局变量 
      MmZeroedPageListHead,MmFreePageListHead,MmStandbyPageListHead,MmModifiedPageListHead,MmModifiedNoWritePageListHead,MmBadPageListHead 
      是6个保存有链表信息的结构,为了便于描述,我们把这个结构叫 PageListHead ,这个结构大小为16个字节,定义如下</P>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -