5
8)阅读控制台命令“vm”相关的代码,并查看执行结果。
阅读 ke/sysproc.c 文件中的 ConsoleCmdVM 函数,学习“vm”命令是如何统计并输出进程的 虚拟地址描述符信息的,注意一下几点:
① 与“pm” ”命令输出的是整个系统的物理存储器的使用情况不同,“vm”命
令输出的是某个进程的 虚拟地址描述符信息,所以“vm”命令使用了一个参数——进程 ID,用来指定一个进程。这个进 程既可以是系统进程,也可以是用户进程; ② 在统计输出指定进程的虚拟地址描述符信息之前要关闭中断,之后要打开中断,
这样可以防止在命令执行的过程中有其它线程分配或者释放虚拟页; ③ EOS 操作系统的进程有 4G 的虚拟地址空间,但并不是所有的虚拟地址空间
都使用虚拟地址描述符 来管理,有一些地址空间是静态的,还有一些地址空间由其他的动态方式来管理(例如系统内存 池); ④ 进程 4G 虚拟地址空间中由虚拟地址描述符所管理空间的低地址和高地址是
固定的,在这段地址空间中,如果有虚拟页被占用,就会使用虚拟地址描述符来标识,并放入链表中管理;
9)启动调试,待 EOS 启动完毕,在 EOS 控制台中输入命令“pt”后按回车。“pt”命令可以输出当前系统中的 进程列表,其中系统进程的 ID 为 1;
在 EOS 控制台中输入命令“vm 1”后按回车,观察命令执行的结果:
6
系统进程中由虚拟地址描述符所管理的虚拟页只会分配给进程的句柄表(句柄表占用一个虚拟页)和 线程的堆栈(堆栈占用两个虚拟页)。结合之前“pt”命令输出的进程和线程信息可知,当前系统中只有 1 个系统进程以及 10 个系统线程,所以在上图中,1 号描述符所包含的一个虚拟页即为系统进程的句柄表,而2到11号这10个描述符所分别包含的两个虚拟页即为 10 个系统线程的堆栈。 10)将LoopApp.exe文件添加到软盘镜像的根目录中,并保存,启动调试,待 EOS 启动完毕,在 EOS 控制台中输入命令“A:\\LoopApp.exe”后按回车。此时就使用 EOS 应用 程序文件 LoopApp.exe 创建了一个应用程序进程,由于此进程执行了一个死循环,所以此进程不 会结束执行,除非关闭虚拟机;
11)切换到“Console-2”,然后输入命令“pt”后按回车。输出的信息如图所示。其中 ID 为 31 的进程就是应用程序进程,ID 为 33 的线程就是应用程序进程的主线程;
7
12)输入命令“vm 1”后按回车,可以查看系统进程中虚拟地址描述符的信息。输出的信息如图所示。与第9步图比较可知,3 号描述符所包含的一个虚拟页即为应用程序进程的句柄表,13号描述符所包含的两个虚拟页即为应用程序进程主线程的堆栈;
13)输入命令“vm 31”后按回车,可以查看应用程序进程中虚拟地址描述符的信息;
8
在进程的 4G 逻辑地址空间中,应用程序进程可以自行管理低 2G 的用户空间。从图 15-6 中的信息可以得知,低 2G 的用户空间又被分为了三部分: ① 0x00000000-0x0000FFFF 由 16 个虚拟页构成的 64KB 静态空间,用于捕捉对空
指针的非法访问;
② 0x00010000-0x7FFEFFFF 由虚拟地址描述符管理的动态空间,用于存储应用程序
进程的代码和数 据。上图显示应用程序进程的代码和数据占用了此空间中的 5 个虚拟页,并且是用从应用程 序的基址 0x00400000 起始的;
③ 0x7FFF0000-0x7FFFFFFF 由 16 个虚拟页构成的 64KB 静态空间,用于捕捉对
空指针的非法访问。
14)在系统进程中分配虚拟页和释放虚拟页,使用修改后的ConsoleCmdVM 函数的函数体替换 ke/sysproc.c 文件中 ConsoleCmdVM 函数的函数体,生成修改后的EOS Kernel项目,启动调试,待 EOS 启动完毕,在 EOS 控制台中输入命令“vm 1”后按回车;
9