内存与进程管理器
==========================
But I fear tomorrow I'll be crying,
Yes I fear tomorrow I'll be crying.
King Crimson'69 -Epitaph
关于Windows NT内存管理器的高层次信息已经够多的了,所以这里不会再讲什么FLAT模型、虚拟内存之类的东西。这里我们只讲具体的底层的东西。我假定大家都了解>i386的体系结构。
目录
==========
00.内核进程线程结构体
01.页表
02.Hyper Space
03.System PTE'S
04.Frame data base (MmPfnDatabase)
05.Working Set
06.向pagefile换页
07.page fault的处理
08.从内存管理器角度看进程的创建
09.上下文切换
0a.某些未公开的内存管理器函数
0b.结语
附录
0c.某些未公开的系统调用
0d.附注及代码分析草稿
00.内核进程线程结构体
===================================
Windows NT中的每一个进程都是EPROCESS结构体。此结构体中除了进程的属性之外还引用了其它一些与实现进程紧密相关的结构体。例如,每个进程都有一个或几个线程,线程在系统中就是ETHREAD结构体。我来简要描述一下存在于这个结构体中的主要的信息,这些信息都是由对内核函数的研究而得知的。首先,结构体中有KPROCESS结构体,这个结构体中又有指向这些进程的内核线程(KTHREAD)链表的指针(分配地址空间),基优先级,在内核模式或是用户模式执行进程的线程的时间,处理器affinity(掩码,定义了哪个处理器能执行进程的线程),时间片值。在ETHREAD结构体中还存在着这样的信息:进程ID、父进程ID、进程映象名、section指针。quota定义了所能使用的分页和非分页池的极限值。VAD(virtual address descriptors)树定义了用户地址空间内存区的状况。关于Working Set的信息定义了在给定时间内有那些物理页是属于进程的。同时还有limit与statistics。ACCESS TOKEN描述了当前进程的安全属性。句柄表描述了进程打开的对象的句柄。该表允许不在每一次访问对象时检查访问权限。在EPROCESS结构体中还有指向PEB的指针。
ETHREAD结构体还包含有创建时间和退出时间、进程ID和指向EPROCESS的指针,启动地址,I/O请求链表和KTHREAD结构体。在KTHREAD中包含有以下信息:内核模式和用户模式线程的创建时间,指向内核堆栈基址和顶点的指针、指向服务表的指针、基优先级与当前优先级、指向APC的指针和指向TEB的指针。KTHREAD中包含有许多其它的数据,通过观察这些数据可以分析出KTHREAD的结构。
01.页表
==================
通常操作系统使用页表来进行内存操作。在Windows NT中,每一个进程都有自己私有的页表(进程的所有线程共享此页表)。相应的,在进程切换时会发生页表的切换。为了加快对页表的访问,硬件中有一个translation lookaside buffer(TLB)。在Windows NT中实现了两级的转换机制。在386+处理器上将虚拟地址转换为物理地址过程(不考虑分段)如下:
Virtual Address
+-------------------+-------------------+-----------------------+
|3 3 2 2 2 2 2 2 2 2|2 2 1 1 1 1 1 1 1 1|1 1 |
|1 0 9 8 7 6 5 4 3 2|1 0 9 8 7 6 5 4 3 2|1 0 9 8 7 6 5 4 3 2 1 0|
+-------------------+-------------------+-----------------------+
| Directory index | Page Table index | Offset in page |
+-+-----------------+----+--------------+-----+-----------------+
| | |
| | |
| Page Directory (4Kb)| Page Table (4Kb) | Frame(4Kb)
| +-------------+ | +-------------+ | +-------------+
| | 0 | | | 0 | | | |
| +-------------+ | +-------------+ | | |
| | 1 | | | 1 | | | |
| +-------------+ | +-------------+ | | |
| | | +->| PTE +-+ | | |
| +-------------+ +-------------+ | | | ----------- |
+->| PDE +-+ | | | +->| byte |
+-------------+ | +-------------+ | | ----------- |
| | | | | | | |
+-------------+ | +-------------+ | | |
| | | | | | | |
... | ... | | |
| 1023 | | | 1023 | | | |
CR3->+-------------+ +----->+-------------+ +--->+-------------+
Windows NT 4.0使用平面寻址。NT的地址空间为4G。这4G地址空间中,低2G(地址0-0x7fffffff)属于当前用户进程,而高2G(0x80000000-0xffffffff)属于内核。在上下文切换时,要更新CR3寄存器的值,结果就更换了用户地址空间,这样就达到了进程间相互隔绝的效果。
注:在Windows NT中,从第4版起,除4Kb的页之外同时还使用了4Mb的页(Pentium及更高)来映射内核代码。但是在Windows NT中没有实际对可变长的页提供支持。
PTE和PDE的格式实际上是一样的。
PTE
+---------------+---------------+---------------+---------------+
|3 3 2 2 2 2 2 2|2 2 2 2 1 1 1 1|1 1 1 1 1 1 | |
|1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0|
+---------------------------------------+-----------------------+
| |T P C U R D A P P U R P|
| Base address 20 bits |R P W C W S W |
| |N T D T |
+---------------------------------------+-----------------------+
一些重要的位在i386+下的定义如下:
---------------------------------------------------------------------------
P - 存在位。此位如果未设置,则在地址转换时会产生异常。一般说来,在一些情况下NT内核会使用未设置此位的PTE。
例如,如果向pagefile换出页,保留这些位可以说明其在页面文件中的位置和pagefile号。
U/S - 是否能从user模式访问页。正是借助于此位提供了对内核空间的保护(通常为高2G)。
RW - 是否能写入
NT使用的为OS设计者分配的空闲位
---------------------------------------------------------------------------
PPT - proto pte
TRN - transition pte
当P位未设置时,第5到第9位即派上用场(用于page fault处理)。它们叫做Protection Mask,样子如下:
--------------------------------------------------------------------------------------
* MiCreatePagingFileMap
9 8 7 6 5
---------
| | | | |
| | | | +- Write Copy
| | | +--- Execute
| | +----- Write
| +------- NO CACHE
+--------- Guard
GUARD | NOCACHE组合就是NO ACCESS
* MmGetPhysicalAddress
函数很短,但能从中获得很多信息。在虚地址0xc0000000 - 0xc03fffff上映射有进程的页表。并且,映射的机制非常精巧。在Directory Table(以下称DT)有1100000000b个表项(对应于地址0xc000..-0xc03ff..)指向自己,也就是说对于这些地址DT用作了页表(Page Table)!如果我们使用,比如说,地址(为方便起见使用二进制)
1100000000.0000000101.0000001001.00b
---------- ---------- --------------
0xc0... 页表选择 页表内偏移
页目录
通过页表101b的1001b号,我们得到了PTE。但这还没完——DT本身映射在地址0xc0300000-0xc0300ffc上。在MmSystemPteBase中有值0xc0300000。为什么这样——看个例子就知道了:
1100000000.1100000000.0000001001.00b
---------- ---------- --------------
0xc0... 0xc0... 页目录偏移
页目录 页表-
页目录
选择
最后,在c0300c00包含着用于目录本身的PDE。这个PDE的基地址的值保存在MmSystemPageDirectory中。同时系统为映射物理页MmSystemPageDirectory保留了一个PTE,这就是MmSystemPagePtes。
这样做能简化寻址操作。例如,如果有PTE的地址,则PTE描述的页的地址就等于PTE<<10。反过来:PTE=(Addr>>10)+0xc0000000。
除此之外,在内核中存在着全局变量MmKseg2Frame = 0x20000。该变量指示在从0x80000000开始的哪个地址区域直接映射到了物理内存,也就是说,此时虚拟地址0x80000000 - 0x9fffffff映射到了物理地址00000000-1f000000。
还有几个有意思的地方。从c0000000开始有个0x1000*0x200=0x200000=2M的描述地址的表(0-7fffffff)。描述这些页的PDE位于地址c0300000-0xc03007fc。对于i486,在地址c0200000-c027fffc应该是描述80000000到a0000000的512MB的表,但对于Pentium在区域0xc0300800-0xc03009fc是4MB的PDE,其描述了从0 到1fc00000的步长为00400000的4M的物理页,也就是说选择了4M的页。对应于这些PDE的虚地址为80000000, 9fffffff。
这样我们就得到了页表的分布:
范围 c0000000 - c01ffffc 用于00000000-7fffffff的页表
范围 c0200000 - c027ffff "吃掉" 4M地址页的地址
范围 c0280000 - c02ffffc 包含用于a0000000 - bfffffff的页
范围 c0300
没有合适的资源?快使用搜索试试~ 我知道了~
计算机系统内核分析5部曲(内核分析5部曲)
共6个文件
txt:6个
需积分: 10 110 下载量 188 浏览量
2009-02-04
15:16:18
上传
评论
收藏 71KB RAR 举报
温馨提示
计算机系统内核分析5部曲(内核分析5部曲,内核分析5部曲)
资源推荐
资源详情
资源评论
收起资源包目录
5部曲.rar (6个子文件)
05 ob.txt 51KB
01 intro.txt 26KB
03 reing.txt 8KB
04 int2e.txt 12KB
02 win32.txt 11KB
06 mem.txt 71KB
共 6 条
- 1
资源评论
bingway
- 粉丝: 42
- 资源: 127
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功