📄 jiurl玩玩win2k内存篇 分页机制 (二).htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0070)http://jiurl.cosoft.org.cn/jiurl/document/JiurlPlayWin2k/MmPaging2.htm -->
<HTML><HEAD><TITLE>JIURL玩玩Win2k内存篇 分页机制 (二)</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></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=宋体>
主页: <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=宋体> 日期: 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=19800
width="96%">
<TBODY>
<TR>
<TD height=1041 vAlign=top width="131%">
<P><FONT face=宋体><B>进程的页目录和页表在虚拟地址空间中的位置</B> </FONT></P>
<P><FONT face=宋体><B>
</B>当执行一条访问内存的指令时,如果寄存器中的分页标志位已经被设置,CPU就自动完成虚拟地址到物理地址的转换,来完成该指令。CPU在转换地址过程中,并不需要页目录和页表的虚拟地址。但是分页标志位被设置之后,CPU会把所有指令中的地址当做虚拟地址转换成物理地址。所以程序中使用的都是虚拟地址。一个进程的页表和页目录是由系统维护的,比如一个进程申请或者释放内存,系统就需要设置对应的一些页表项。系统需要访问页目录和页表,但是系统只能使用虚拟地址,所以系统必须把页目录和页表映射到地址空间中。对应4G地址空间的1024个页表被顺序映射到了从0xC0000000到0xC03FFFFF的4M地址空间。对应第一个4M地址空间的页表,被映射到了0xC0000000开始的第一个4K地址空间(0xC0000000开始的4K)。对应第二个4M地址空间的页表,被映射到了0xC0000000开始的第二个4K地址空间(0xC0001000开始的4K),以此类推。页目录被映射到了0xC0300000开始处的4K地址空间。0xC0000000到0xC03FFFFF的4M地址空间位于高2G的系统地址空间内,需要ring0的权限才能访问。<BR><BR><B>有效页目录项和有效页表项</B></FONT></P>
<P><FONT face=宋体><B>
</B>页目录项和页表项的最低位,第0位,指明了一页是否映射了物理内存。最低位为1,有效(Valid),表示该页映射了物理内存。页目录项和页表项,4个字节,32bit,有着差不多的结构。使用
Win2k DDK 所附带的内核调试器,Kernel Debugger (KD) ,我们可以得到有效的页目录项和页表项的结构定义,对于使用 X86
CPU 的系统,该结构定义如下<BR><BR>!strct HARDWARE_PTE_X86<BR>struct _HARDWARE_PTE_X86
(sizeof=4)<BR>+0 bits0-0 Valid<BR>+0 bits1-1 Write<BR>+0 bits2-2
Owner<BR>+0 bits3-3 WriteThrough<BR>+0 bits4-4 CacheDisable<BR>+0 bits5-5
Accessed<BR>+0 bits6-6 Dirty<BR>+0 bits7-7 LargePage<BR>+0 bits8-8
Global<BR>+0 bits9-9 CopyOnWrite<BR>+0 bits10-10 Prototype<BR>+0 bits11-11
reserved<BR>+0 bits12-31 PageFrameNumber<BR><BR>bits12-31
PageFrameNumber:<BR>页目录项或者页表项的第12到第31位,长20位。物理页的页帧号。(将这32位和0xFFFFF000做与运算,就得到了该4KB物理页第一个字节的地址)由于页的大小是4KB,所以只需要20位,就可以寻址4G大小范围内的每一页。对于页目录项来说,所得的物理页中放着的是一个页表。<BR><BR>bits0-0
Valid: <BR>为0无效,该页没有映射物理内存。为1有效。该页映射了物理内存。<BR><BR>bits1-1
Write:<BR>为0该页只读。为1该页可以读写。<BR><BR>bits2-2
Owner:<BR>为0访问该页需要ring0权限,只有核心态(kernel-mode)的代码才可以访问。<BR>为1访问该页ring3权限就可以,用户态(user-mode)代码就可以访问。<BR><BR>bits3-3
WriteThrough:<BR>为0 对相关页使用 write-back caching 策略。为1 对相关页使用 write-through
caching
策略。<BR>直写式(Write-through),在CPU向Cache写入的同时,也把数据写入相应内存单元。保证Cache和内存中相应单元数据的一致性。直写式速度慢,而且有些操作是不必要的,比如CPU连续多次更新一个Cache单元的内容,将导致相应内存单元连续多次被写入,而效果其实和写入最后一次更新是一样的。<BR>回写式(Write-back),CPU修改了Cache的内容后,并不立即修改内存中相应的单元。只有当回写操作被执行的时候,才修改相应内存单元。比如该Cache单元的内容从Cache中撤销时触发回写操作。回写式速度快,也避免了一些不必要的操作。<BR>如果CR0中的CD
(cache
disable)标志为1,则处理器忽略WriteThrough标志。CD标志,CR0寄存器的第30bit<BR>。观察发现,初始化之后的Win2k中,该位为0。也就是说页目录项和页表项中的WriteThrough标志是起作用的。<BR><BR>bits4-4
CacheDisable:<BR>为0 允许Cache该页。为1 禁止Cache该页。<BR>如果CR0中的CD (cache
disable)标志为1,则处理器忽略CacheDisable标志。CD标志,CR0寄存器的第30bit<BR>。观察发现,初始化之后的Win2k中,该位为0。也就是说页目录项和页表项中的CacheDisable标志是起作用的。<BR><BR>bits5-5
Accessed:<BR>为0 该页没有被访问(读出或者写入)过。为1 该页被访问(读出或者写入)过。<BR><BR>bits6-6
Dirty:<BR>为0 该页中的内容没有被改动过。 为1 该页中的内容已经被改动过了(被写过)。<BR><BR>bits7-7
LargePage:<BR>为0 表示页大小为4K,为1 表示页大小为4M。<BR><BR>bits8-8 Global:<BR>为0 表示不是
global page。为1 表示是一个 global page。<BR>如果CR4中的 page global enable (PGE) 标志为1
,表示允许 page global,那么当进程转换时在 TLB(Translation lookaside buffer ) 高速缓存中的
global page
不会失效。用来防止常用页(比如内核或者操作系统的执行代码所在页)被换出TLB高速缓存。寄存器CR4的PGE标志是第7位。观察发现,初始化之后的Win2k中,该位为1。<BR><BR>bits9-9
CopyOnWrite:<BR>用于 Copy-on-Write 机制。<BR><BR>bits10-10 Prototype:<BR>用于
进程间内存共享 机制。<BR><BR>bits11-11
reserved:<BR>保留<BR><BR><BR><B>页目录和页表</B></FONT></P>
<P><FONT face=宋体> 我们可以使用 SoftICE 获得指定进程的页目录,方法如下,首先不加参数的
addr 命令,将列出当前系统中的进程。然后 addr 进程名 ,切换到该进程的地址空间。然后 dd c0300000 l 1000
,将会在命令窗口输出0xc0300000处的0x1000字节(16进制,也就是4K字节)。然后退出 SoftICE,使用 Symbol Loader
的菜单中的 File -> Save SoftICE History AS..
就可以把刚才输出的内容保存到文件中。每个进程的页目录都映射到了0xc0300000处,所以我们就得到了页目录的内容。<BR><BR>我也写了一个叫
<A
href="http://jiurl.cosoft.org.cn/jiurl/document/JiurlPlayWin2k/JiurlPdPtSee.zip">JiurlPdPtSee</A>
的程序,可以输出指定进程的页目录和页表。以下的内容就来自这个程序。<BR><BR>打开的一个记事本进程的页目录:<BR><BR>c0300000:
05f5b067 058ae067 067b5067 00eae067<BR>c0300010: 03bfa067 00000000
00000000 00000000<BR>c0300020: 00000000 00000000 00000000
00000000<BR>c0300030: 00000000 00000000 00000000 00000000<BR>c0300040:
00000000 00000000 00000000 00000000<BR>c0300050: 00000000 00000000
00000000 00000000<BR>c0300060: 00000000 00000000 00000000
00000000<BR>c0300070: 00000000 00000000 00000000 00000000<BR>c0300080:
00000000 00000000 00000000 00000000<BR>c0300090: 00000000 00000000
00000000 00000000<BR>c03000a0: 00000000 00000000 00000000
00000000<BR>c03000b0: 00000000 00000000 00000000 00000000<BR>c03000c0:
00000000 00000000 00000000 00000000<BR>c03000d0: 00000000 00000000
00000000 00000000<BR>c03000e0: 00000000 00000000 00000000
00000000<BR>c03000f0: 00000000 00000000 00000000 00000000<BR>c0300100:
043b1067 00000000 00000000 00000000<BR>c0300110: 00000000 00000000
00000000 00000000<BR>c0300120: 00000000 00000000 00000000
00000000<BR>c0300130: 00000000 00000000 00000000 00000000<BR>c0300140:
00000000 00000000 00000000 00000000<BR>c0300150: 00000000 00000000
00000000 00000000<BR>c0300160: 00000000 00000000 00000000
00000000<BR>c0300170: 00000000 00000000 00000000 00000000<BR>c0300180:
00000000 00000000 00000000 00000000<BR>c0300190: 00000000 00000000
00000000 00000000<BR>c03001a0: 00000000 00000000 00000000
00000000<BR>c03001b0: 00000000 00000000 00000000 00000000<BR>c03001c0:
00000000 00000000 00000000 00000000<BR>c03001d0: 00000000 00000000
00000000 00000000<BR>c03001e0: 00000000 00000000 00000000
00000000<BR>c03001f0: 00000000 00000000 00000000 00000000<BR>c0300200:
00000000 00000000 00000000 00000000<BR>c0300210: 00000000 00000000
00000000 00000000<BR>c0300220: 00000000 00000000 00000000
00000000<BR>c0300230: 00000000 00000000 00000000 00000000<BR>c0300240:
00000000 00000000 00000000 00000000<BR>c0300250: 00000000 00000000
00000000 00000000<BR>c0300260: 00000000 00000000 00000000
00000000<BR>c0300270: 00000000 00000000 00000000 00000000<BR>c0300280:
00000000 00000000 00000000 00000000<BR>c0300290: 00000000 00000000
00000000 00000000<BR>c03002a0: 00000000 00000000 00000000
00000000<BR>c03002b0: 00000000 00000000 00000000 00000000<BR>c03002c0:
00000000 00000000 00000000 00000000<BR>c03002d0: 00000000 00000000
00000000 00000000<BR>c03002e0: 00000000 00000000 00000000
00000000<BR>c03002f0: 00000000 00000000 00000000 00000000<BR>c0300300:
00000000 00000000 00000000 00000000<BR>c0300310: 00000000 00000000
00000000 00000000<BR>c0300320: 00000000 00000000 00000000
00000000<BR>c0300330: 00000000 00000000 00000000 00000000<BR>c0300340:
00000000 00000000 00000000 00000000<BR>c0300350: 00000000 00000000
00000000 00000000<BR>c0300360: 00000000 00000000 00000000
00000000<BR>c0300370: 00000000 00000000 00000000 00000000<BR>c0300380:
00000000 00000000 00000000 00000000<BR>c0300390: 00000000 00000000
00000000 00000000<BR>c03003a0: 00000000 00000000 00000000
00000000<BR>c03003b0: 00000000 00000000 00000000 00000000<BR>c03003c0:
00000000 00000000 00000000 00000000<BR>c03003d0: 00000000 00000000
00000000 00000000<BR>c03003e0: 00000000 00000000 00000000
00000000<BR>c03003f0: 00000000 00000000 00000000 00000000<BR>c0300400:
00000000 00000000 00000000 00000000<BR>c0300410: 00000000 00000000
00000000 00000000<BR>c0300420: 00000000 00000000 00000000
00000000<BR>c0300430: 00000000 00000000 00000000 00000000<BR>c0300440:
00000000 00000000 00000000 00000000<BR>c0300450: 00000000 00000000
00000000 00000000<BR>c0300460: 00000000 00000000 00000000
00000000<BR>c0300470: 00000000 00000000 00000000 00000000<BR>c0300480:
00000000 00000000 00000000 00000000<BR>c0300490: 00000000 00000000
00000000 00000000<BR>c03004a0: 00000000 00000000 00000000
00000000<BR>c03004b0: 00000000 00000000 00000000 00000000<BR>c03004c0:
00000000 00000000 00000000 00000000<BR>c03004d0: 00000000 00000000
00000000 00000000<BR>c03004e0: 00000000 00000000 00000000
00000000<BR>c03004f0: 00000000 00000000 00000000 00000000<BR>c0300500:
00000000 00000000 00000000 00000000<BR>c0300510: 00000000 00000000
00000000 00000000<BR>c0300520: 00000000 00000000 00000000
00000000<BR>c0300530: 00000000 00000000 00000000 00000000<BR>c0300540:
00000000 00000000 00000000 00000000<BR>c0300550: 00000000 00000000
00000000 00000000<BR>c0300560: 00000000 00000000 00000000
00000000<BR>c0300570: 00000000 00000000 00000000 00000000<BR>c0300580:
00000000 00000000 00000000 00000000<BR>c0300590: 00000000 00000000
00000000 00000000<BR>c03005a0: 00000000 00000000 00000000
00000000<BR>c03005b0: 00000000 00000000 00000000 00000000<BR>c03005c0:
00000000 00000000 00000000 00000000<BR>c03005d0: 00000000 00000000
00000000 00000000<BR>c03005e0: 00000000 00000000 00000000
00000000<BR>c03005f0: 00000000 00000000 00000000 00000000<BR>c0300600:
00000000 00000000 00000000 00000000<BR>c0300610: 00000000 00000000
00000000 00000000<BR>c0300620: 00000000 00000000 00000000
00000000<BR>c0300630: 00000000 00000000 00000000 00000000<BR>c0300640:
00000000 00000000 00000000 00000000<BR>c0300650: 00000000 00000000
00000000 00000000<BR>c0300660: 00000000 00000000 00000000
00000000<BR>c0300670: 00000000 00000000 00000000 00000000<BR>c0300680:
00000000 00000000 00000000 00000000<BR>c0300690: 00000000 00000000
00000000 00000000<BR>c03006a0: 00000000 00000000 00000000
00000000<BR>c03006b0: 00000000 00000000 00000000 00000000<BR>c03006c0:
00000000 00000000 00000000 00000000<BR>c03006d0: 00000000 00000000
00000000 0423a067<BR>c03006e0: 00000000 00000000 00000000
00000000<BR>c03006f0: 00000000 00000000 00000000 00000000<BR>c0300700:
00000000 00000000 00000000 00000000<BR>c0300710: 00000000 00000000
00000000 00000000<BR>c0300720: 00000000 00000000 00000000
00000000<BR>c0300730: 00000000 00000000 00000000 00000000<BR>c0300740:
00000000 00000000 00000000 00000000<BR>c0300750: 00000000 00000000
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -