物理存储器与进程逻辑地址空间的管理实验报告

更新时间:2024-06-02 01:08:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

操作系统 实 验 报 告

课程名称 实验项目名称 学号 操作系统实验 课程编号 0906553 物理存储器与进程逻辑地址空间的管理 年级 计算机科学姓名 计算机科学与技专业 与技术 学生所在学院 术学院 实验室名称地点

指导教师

哈尔滨工程大学 计算机科学与技术学院

物理存储器与进程逻辑地址空间的管理

一. 实验概述:

1.实验名称:物理存储器与进程逻辑地址空间的管理 2.实验目的:

1)通过查看物理存储器的使用情况,并练习分配和回收物理内存,从而掌握物理存储器的管理方法;

2)通过查看进程逻辑地址空间的使用情况,并练习分配和回收虚拟内存,从而掌握进程逻辑地址空间的 管理方法。 3.实验类型:验证、设计 4.实验内容:

1)准备实验,创建一个EOS Kernel项目;

2)阅读控制台命令“pm”相关的源代码,并查看其执行的结果; 3)分配物理页和释放物理页;

4)阅读控制台命令“vm”相关的源代码,并查看执行的结果; 5)在系统进程中分配虚拟页和释放虚拟页; 6)在应用程序进程中分配虚拟页和释放虚拟页。 二.实验环境

操作系统:windows XP 编译器:Tevalaton OS Lab 语言:C 三.实验过程

1.设计思路和流程图:

MiAllocateAny函数流程图:

1

MiFreePages函数流程图:

2.实验过程:

1)新建一个 EOS Kernel 项目;

2)阅读 ke/sysproc.c 文件中的 ConsoleCmdPhysicalMemory 函数,学习“pm”命令是如何统计并输出物理存储器信息的。在阅读的过程中应注意:

①在统计输出物理存储器信息之前要关闭中断,之后要打开中断,这样可以防止在命令执行的过程 中有其它线程分配或者释放物理页;

②全局变量 MiTotalPageFrameCount 保存了物理页的总数。每个物理页的大小是 4KB,由宏 PAGE_SIZE 定义;

③全局变量 MiZeroedPageCount 和 MiFreePageCount 分别保存了零页和空闲页的数量;

④计算已用物理页数量的方法是:物理页总数减去零页数量,再减去空闲页数量。 3)生成所创建的项目,启动调试,待EOS启动完毕,在EOS控制台中输入命令“pm”后回车,观察命令执行的结果。

2

4)将修改后的ConsoleCmdPhysicalMemory 函数进行替换,主要是在原有代码的后面添加了分配物理页和释放物理页的代码,生成修改后的EOS Kernel项目,启动调试,待 EOS 启动完毕,在 EOS 控制台中输入命令“pm”后按回车;

5)结束调试,在调用 MiAllocateAnyPages 函数的代码行添加一个断点,在调用 MiFreePages 函数的代码行添加一个断点;

6)启动调试,待 EOS 启动完毕,在 EOS 控制台中输入命令“pm”后按回车,pm 命令开始执行后,会在调用 MiAllocateAnyPages 函数的代码行处中断,按 F11(逐语句)调试进入 MiAllocateAnyPages 函数;

3

按 F10(逐过程)单步调试 MiAllocateAnyPages 函数的执行过程:

7)继续执行,,会在调用 MiFreePages 函数的代码行处中断,按F11(逐语句)调试进入 MiFreePages 函数;

按 F10(逐过程)单步调试 MiFreePages 函数的执行过程:

4

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

15)在 ke/sysproc.c 文件的ConsoleCmdVM 函数中,在调用MmAllocateVirtual——Memory 函数的代码行添加一个断点,在调用 MmFreeVirtualMemory 函数的代码行添加一 个断点;

16)启动调试,待 EOS 启动完毕,在 EOS 控制台中输入命令“vm 1”后按回车,vm 命令开始执行后,会在调用 MmAllocateVirtualMemory 函数的代码行处中断。此时要注意参数 BaseAddress 和 RegionSize 初始化的值。按 F11(逐过程)调试进入 MmAllocateVirtualMemory 函数;

10

17)按 F10(逐过程)单步调试 MmAllocateVirtualMemory 函数的执行过程,继续执行,,会在调用 MmFreeVirtualMemory 函数的代码行处中断。此时要注意参数 BaseAddress 和 RegionSize 初始化的值。按 F11 调试进入 MmFreeVirtualMemory 函数;

11

12

18)尝试在调用 MmAllocateVirtualMemory 函数时将 RegionSize 参数的值设置为 PAGE_SIZE+1 或者 PAGE_SIZE*2+1。观察“输出”窗口中转储的信息,并说明申请虚拟内存的大小与实际分配的大 小之间的关系,以及分配的虚拟内存大小会对分配的虚拟地址产生什么样的影响。将“输出”窗 口中转储的信息保存在文本文件中;

19)尝试在调用 MmAllocateVirtualMemory 函数时将 BaseAddress 参数的值设置为已经被占用的虚拟 内存,例如 0xA0000000,观察“输出”窗口中转储的信息。将“输出”窗口中转储的信息保存在 文本文件中;

13

20)尝试在调用 MmAllocateVirtualMemory 函数时将 RegionSize 参数的值设置为 PAGE_SIZE*2,将 BaseAddress 参数的值设置为 0xA0017004,观察“输出”窗口中转储的信息,并说明申请虚拟内 存的大小与实际分配的大小之间的关系,以及申请的虚拟地址会对分配的虚拟内存大小产生什么 样的影响。将“输出”窗口中转储的信息保存在文本文件中;

21)创建一个EOS应用程序,调用API函数VirtualAlloc,分配一个整型变量所需的空间,并使用一个整型变量的指针指向这个空间。

修改整型变量的值为 0xFFFFFFFF。在修改前输出整型变量的值,在修改后再输出整型变量的值。

调用 API 函数 Sleep,等待 10 秒钟,调用 API 函数 VirtualFree,释放之前分配的整型变量的空间,进入死循环,这样应用程序就不会结束。 #include “EOSApp.h”

int main(int argc,char* argv[]){

//启动调试EOS应用程序前要特别注意下面的问题:

// 1、如果要在调试应用程序时能够调试进入内核显示对应的源码,必须使用EOS

核心项目编译生成完全版本的SDK 文件夹,然后使用此文件夹覆盖应用程序项目中的SDK 文件夹,并且EOS核心项目在磁盘上的位置不能改变。

2、在启动调试应用程序之前必须首先删除禁用所有的断点,在断点中断(int 3)

被命中后才能重新添加启用断点,否则启动调试会失败。 #ifdef_DEBUG

_asm(“int$3\\n nop”);

#endif

INT* p;

//调用API函数VirtualAlloc,分配一个整型变量所需的空间,并使用一个整

14

型变量的指针指向这个空间

If(p=VirtualAlloc(0,sizeof(int),MEM_RESERVE|MEM_COMMIT)){

printf(“Allocated %d bytes virtual memory of 0x%x\\n\\n”,sizeof(int),d);

//输出原始整型变量的值

printf(\ //修改整型变量的值为0xFFFFFFFF *p=0xFFFFFFFF;

//输出修改后的整型变量的值

printf(\ printf(\ // 调用API函数Sleep,等待10秒钟 Sleep(10000);

// 调用API函数VirtualFree,释放之前分配的整型变量的空间 if(VirtualFree(p,0,MEM_RELEASE))

printf(\ else{

//若释放不成功,打印输出错误,并返回-1。 printf(\ return -1;

}

return 0; }

22)代码修改完毕后,生成EOS应用程序项目,启动调试,输出结果如图所示。

在应用程序分配虚拟页后,利用10秒后才释放虚拟页的间隙,可以在控制台2中执行命令“vm 31”, 查看此时应用程序进程的虚拟地址描述符信息,在应用程序释放虚拟页后,可以在控制台 2 中再 次执行命令“vm 31”,查看此时应用程序进程的虚拟地址描述符信息。

15

提示:API 函数 VirtualAlloc 定义在 api/eosapi.c 文件,此 API 函数主要调用了 EOS 内核函 数 MmAllocateVirtualMemory,在 EOS 应用程序中调用函数 VirtualAlloc 时,除了使用 MEM_RESERVE 标志外,还必须使用 MEM_COMMIT 标志;

API 函数 VirtualFree 定义在 api/eosapi.c 文件,此 API 函数主要调用了 EOS 内核函 数 MmFreeVirtualMemory,在 EOS 应用程序中调用函数 VirtualFree 时,要使用 MEM_RELEASE 标志。

3. 主要数据结构、实现代码及其说明 typedef struct _MMPFN {

ULONG Unused : 9; // 未用

ULONG PageState : 3; // 物理页的状态

ULONG Next : 20; // 下一个物理页的页框号 }MMPFN, *PMMPFN;

typedef enum _PAGE_STATE { ZEROED_PAGE, // 零页 FREE_PAGE, // 自由页 BUSY_PAGE, // 占用页 } PAGE_STATE;

// 虚拟地址描述符

typedef struct _MMVAD{

ULONG_PTR StartingVpn; // 被使用区域的开始虚页框号 ULONG_PTR EndVpn; // 被使用区域的结束虚页框号

16

LIST_ENTRY VadListEntry; // 链表项,用于将描述同一地址空间的所有VAD串成链表

}MMVAD, *PMMVAD; // 虚拟地址描述符链表

typedef struct _MMVAD_LIST{

ULONG_PTR StartingVpn; // 记录的进程地址空间的开始虚页号 ULONG_PTR EndVpn; // 记录的进程地址空间的结束虚页号 LIST_ENTRY VadListHead; // VAD链表头 }MMVAD_LIST, *PMMVAD_LIST;

四.实验体会

在本次实验中,通过调试EOS操作系统中物理存储空间和虚拟存储空间的分配和回收函数,对操作系统的内存管理机制和实现有了更进一步的认识,对于自己动手设计应用程序进程中分配虚拟页和释放虚拟页的程序,需要首先了解代码的设计思路以及各个变量所代表的含义,在实践的过程中,逐渐了解了虚拟内存分配和释放时的函数调用关系,并通过阅读函数源代码理解了具体的逻辑顺序,加深了对编程的掌握,尤其是对操作系统内存分配的简单掌握。

17

本文来源:https://www.bwwdw.com/article/ryl6.html

Top