061324张耀第四讲 物理存储器与进程逻辑地址空间的管理.docx

上传人:b****5 文档编号:7384773 上传时间:2023-01-23 格式:DOCX 页数:15 大小:527.85KB
下载 相关 举报
061324张耀第四讲 物理存储器与进程逻辑地址空间的管理.docx_第1页
第1页 / 共15页
061324张耀第四讲 物理存储器与进程逻辑地址空间的管理.docx_第2页
第2页 / 共15页
061324张耀第四讲 物理存储器与进程逻辑地址空间的管理.docx_第3页
第3页 / 共15页
061324张耀第四讲 物理存储器与进程逻辑地址空间的管理.docx_第4页
第4页 / 共15页
061324张耀第四讲 物理存储器与进程逻辑地址空间的管理.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

061324张耀第四讲 物理存储器与进程逻辑地址空间的管理.docx

《061324张耀第四讲 物理存储器与进程逻辑地址空间的管理.docx》由会员分享,可在线阅读,更多相关《061324张耀第四讲 物理存储器与进程逻辑地址空间的管理.docx(15页珍藏版)》请在冰豆网上搜索。

061324张耀第四讲 物理存储器与进程逻辑地址空间的管理.docx

061324张耀第四讲物理存储器与进程逻辑地址空间的管理

操作系统

实验报告

课程名称

操作系统实验

课程编号

0906553

实验项目名称

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

学号

2011061324

年级

2011

姓名

张耀

专业

计算机科学与技术

学生所在学院

计算机科学与技术

指导教师

印桂生

实验室名称地点

21B276

哈尔滨工程大学

计算机科学与技术学院

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

一、实验概述

1.实验名称

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

2.实验目的

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

(2)通过查看进程逻辑地址空间的使用情况,并练习分配和回收虚拟内存,从而掌握进程逻辑地址空间的。

管理方法。

3.实验类型

验证性和设计性实验

4.实验内容

(1)准备实验;

(2)执行控制台命令“pm”,查看物理存储器的信息;

(3)分配物理页和释放物理页;

(4)阅读控制台命令“vm”相关的源代码,并查看其执行的结果;

(5)在系统进程中分配虚拟页和释放虚拟页;

(6)在应用程序进程中分配虚拟页和释放虚拟页。

二、实验环境

在OSLab实验环境的基础上,利用EOS操作系统,由汇编语言及C语言编写代码,对需要的项目进行生成、调试、查看和修改,并通过EOS应用程序使内核从源代码变为可以在虚拟机上使用。

三、实验过程

1.设计思路和流程图

图3.1.1MiAllocateAnyPages函数的流程图

图3.1.2MiFreePages函数的流程图

2.需要解决的问题及解答

(1)MmAllocateVirtualMemory函数的执行过程,要求给出监视窗口BaseAddress和RegionSize个变量前后变化截图界面。

答:

BaseAddress和RegionSize个变量前后变化截图界面如下图所示。

图3.2.1进入MmAllocateVirtualMemory前两个变量的情况

图3.2.2完成MmAllocateVirtualMemory后两个变量的情况

 

(2)MmFreeVirtualMemory函数的执行过程,要求给出监视窗口BaseAddress和RegionSize个变量前后变化截图界面。

答:

BaseAddress和RegionSize个变量前后变化截图界面如下图所示。

图3.2.3进入MmFreeVirtualMemory前两个变量的情况

图3.2.4完成MmFreeVirtualMemory后两个变量的情况

(3)按F10单步调试MiAllocateAnyPages函数的执行过程,尝试回答下面的问题:

①本次分配的物理页的数量是多少?

分配的物理页的页框号是多少?

②物理页是从空闲页链表中分配的?

还是从零页链表中分配的?

③哪一行语句减少了空闲页的数量?

哪一行语句将刚刚分配的物理页由空闲状态修改为忙状态?

④绘制MiAllocateAnyPages函数的流程图。

答:

①本次分配的物理页的数量是1,分配的物理页的页框号是0x409;②物理页是从空闲页链表中分配的,;③第226行MiFreePageListHead=MiGetPfnDatabaseEntry(Pfn)->Next;和第227行MiFreePageCount--;减少了空闲页的数量,第229行将刚刚分配的物理页由空闲状态修改为忙状态;④见实验过程开头流程图部分。

(4)按F10单步调试MiFreePages函数的执行过程,尝试回答下面的问题:

①本次释放的物理页的数量是多少?

释放的物理页的页框号是多少?

释放的物理页是之前分配的物理页吗?

②释放的物理页是被放入了空闲页链表中?

还是零页链表中?

③绘制MiFreePages函数的流程图。

答:

①本次释放的物理页的数量是1,释放的物理页的页框号0x409,释放的物理页是之前分配的物理页;②释放的物理页被放入了空闲页链表中;③见实验过程开头流程图部分。

(5)按F10单步调试MmAllocateVirtualMemory函数的执行过程,尝试回答下面的问题:

①分配的虚拟页的起始地址是多少?

分配的虚拟页的数量是多少?

它们和参数BaseAddress和RegionSize初始化的值有什么样的关系?

②分配虚拟页的同时有为虚拟页映射实际的物理页吗?

这是由哪个参数决定的?

③分配的虚拟页是在系统地址空间(高2G)还是在用户地址空间(低2G)?

这是由哪个参数决定的?

④参考MiReserveAddressRegion函数的定义和注释,说明该函数的功能。

答:

①分配的虚拟页的起始地址是0xa0003000,分配的虚拟页的数量是1,BaseAddress和RegionSize初始化的值是期望保留或者提交的地址区域的起始地址和大小;②分配虚拟页的同时有为虚拟页映射实际的物理页,这是由第三个参数AllocationType决定的;③分配的虚拟页是在系统地址空间(高2G),这是由第四个参数SystemVirtual决定的;④MiReserveAddressRegion函数的功能是保留一段虚拟地址区域。

(6)按F10单步调试MmFreeVirtualMemory函数的执行过程,尝试回答下面的问题:

①本次释放的虚拟地址是多少?

释放的虚拟页是之前分配的虚拟页吗?

②参考MiFindReservedAddressRegion函数、MiFreeAddressRegion函数和MiDecommitPages函数的定义和注释,说明这些函数的功能。

答:

①本次释放的虚拟地址是0xa0003000,是之前分配的虚拟页;②MiFindReservedAddressRegion函数用于查找已保留地址区域,如果目标区域非已保留区域则返回失败,MiFreeAddressRegion函数用于释放已保留地址区域和MiDecommitPages函数用于释放映射在连续虚拟页框上的物理页框。

(7)在本实验3.3中,如果分配了物理页后,没有回收,会对EOS操作系统造成什么样的影响?

目前EOS操作系统内核函数MiAllocateAnyPages能处理所有物理页被分配完毕的情况吗?

例如在没有可分配的物理页的情况下调用该内核函数,是否会返回失败?

如果内核函数MiAllocateAnyPages还不能处理这种极端情况,尝试修改代码解决这个问题。

答:

如果分配了物理页后,没有回收,将会使可分配自由页和零页越来越少,最终导致内存溢出,系统无法运行。

目前EOS操作系统内核函数MiAllocateAnyPages不能处理所有物理页被分配完毕的情况,在没有可分配的物理页的情况下,不会分配物理页,但仍然会返回成功,添加以下代码即可:

Else{

returnSTATUS_MEMORY_NOT_ALLOCATED;

}

(8)在本实验3.3中,在分配物理页时是调用的内核函数MiAllocateAnyPages,该函数会优先分配空闲页,尝试修改代码,调用内核函数MiAllocateZeroedPages优先分配零页,并调试分配零页的情况。

尝试从性能的角度分析内核函数MiAllocateAnyPages和MiAllocateZeroedPages。

尝试从安全性的角度分析分配零页的必要性。

答:

将MiAllocateAnyPages(1,PfnArray);修改为MiAllocateZeroedPages(1,PfnArray);即可。

系统启动时,所有空闲物理页都是未初始化的,此时零页链表为空,MiAllocateAnyPages函数可以直接从自由页链表分配,而MiAllocateZeroedPages函数会对从自由页链表中分配的每一页进行零初始化,确保所有分配页都是被零初始化的,再进行分配,因此MiAllocateZeroedPages函数效率较低。

但因为MiAllocateZeroedPages函数对自由页进行了初始化,减小了出错的可能性,从而安全性较高。

4.主要数据结构、实现代码及其说明

typedefstruct_MMPFN

{

ULONGUnused:

9;//未用

ULONGPageState:

3;//物理页的状态

ULONGNext:

20;//下一个物理页的页框号

}MMPFN,*PMMPFN;

typedefenum_PAGE_STATE{

ZEROED_PAGE,//零页

FREE_PAGE,//自由页

BUSY_PAGE,//占用页

}PAGE_STATE;

//虚拟地址描述符

typedefstruct_MMVAD{

ULONG_PTRStartingVpn;//被使用区域的开始虚页框号

ULONG_PTREndVpn;//被使用区域的结束虚页框号

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

}MMVAD,*PMMVAD;

//虚拟地址描述符链表

typedefstruct_MMVAD_LIST{

ULONG_PTRStartingVpn;//记录的进程地址空间的开始虚页号

ULONG_PTREndVpn;//记录的进程地址空间的结束虚页号

LIST_ENTRYVadListHead;//VAD链表头

}MMVAD_LIST,*PMMVAD_LIST;

实现代码如下:

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

{

printf("Allocated%dbytesvirtualmemoryof0x%x\n\n",sizeof(int),d);

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

printf("virtualmemoryoriginalvalue:

0x%x\n\n",*d);

//修改整型变量的值为xFFFFFFFF

*p=0xFFFFFFFF;

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

printf("virtualmemorynewvalue:

0x%x\n\n",*d);

printf("\nWaitfor10seconds\n");

//调用API函数Sleep,等待秒钟

Sleep(10000);

//调用API函数VirtualFree,释放之前分配的整型变量的空间

if(VirtualFree(d,0,MEM_RELEASE))

printf("\nRealeasevirtualmemorysuccess!

\n");

else

{

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

printf("VirtualFreeError!

\n");

return-1;

}

printf("\nEndlessloop!

");

//进入死循环

for(;;){;}

return0;

}

else

{

//若分配不成功,打印输出错误,并返回-1。

printf("VirtualAllocError!

\n");

return-1;

}

5.源程序并附上注释

#include"EOSApp.h"

intmain(intargc,char*argv[])

{

#ifdef_DEBUG

__asm("int$3\nnop");

#endif

/*TODO:

在此处添加自己的代码*/

//使用一个整型变量的指针指向这个空间

INT*p;

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

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

{

printf("Allocated%dbytesvirtualmemoryof0x%x\n\n",sizeof(int),d);

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

printf("virtualmemoryoriginalvalue:

0x%x\n\n",*d);

//修改整型变量的值为xFFFFFFFF

*p=0xFFFFFFFF;

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

printf("virtualmemorynewvalue:

0x%x\n\n",*d);

printf("\nWaitfor10seconds\n");

//调用API函数Sleep,等待秒钟

Sleep(10000);

//调用API函数VirtualFree,释放之前分配的整型变量的空间

if(VirtualFree(d,0,MEM_RELEASE))

printf("\nRealeasevirtualmemorysuccess!

\n");

else

{

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

printf("VirtualFreeError!

\n");

return-1;

}

printf("\nEndlessloop!

");

//进入死循环

for(;;){;}

return0;

}

else

{

//若分配不成功,打印输出错误,并返回-1。

printf("VirtualAllocError!

\n");

return-1;

}

printf("Helloworld!

\n");

return0;

}

6.程序运行时的初值和运行结果

启动EOS,在EOS控制台中输入命令“pm”后按回车,控制台输出结果如下图所示。

图3.6.1

由图中我们可以看出,系统共有物理页8176个,内存大小33488896Byte,零页0个,自由页7126个,占用页1050个。

使用pm.c文件中ConsoleCmdPhysicalMemory函数的函数体替换ke/sysproc.c文件中ConsoleCmdPhysicalMemory函数的函数体,待EOS启动完毕,在EOS控制台中输入命令“pm”后按回车,控制台输出结果如下图所示。

图3.6.2

从图中我们看出,分配了一个物理页后,零页数量不变,自由页数量减一,占用页数量加一;释放一个物理页后,零页数量不变,自由页数量加一,占用页数量减一。

在EOS控制台中输入命令“vm1”后按回车,控制台输出结果如下图所示。

图3.6.3

如图所示,1号描述符所包含的一个虚拟页即为系统进程的句柄表,而2到11号这10个描述符所分别包含的两个虚拟页即为10个系统线程的堆栈。

将LoopApp.exe文件添加到软盘镜像的根目录中,在EOS控制台中输入命令“A:

\LoopApp.exe”后按回车,此时按Ctrl+F2切换到“Console-2”,然后输入命令“vm1”后按回车。

控制台输出如下图所示。

图3.6.4

输入命令“vm31”后按回车,可以查看应用程序进程中虚拟地址描述符的信息。

如下图所示。

图3.6.5

使用vm.c文件中ConsoleCmdVM函数的函数体替换ke/sysproc.c文件中ConsoleCmdVM函数的函数体,待EOS启动完毕,在EOS控制台中输入命令“vm1”后按回车,控制台输出结果如下图所示。

图3.6.6

创建一个EOS应用程序,并编写代码完成下列功能:

1.调用API函数VirtualAlloc,分配一个整型变量所需的空间,并使用一个整型变量的指针指向这

个空间。

2.修改整型变量的值为0xFFFFFFFF。

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

3.调用API函数Sleep,等待10秒钟。

4.调用API函数VirtualFree,释放之前分配的整型变量的空间。

5.进入死循环,这样应用程序就不会结束。

首先创建一个EOS应用程序,并修改其中EOSApp.c文件的代码,如下图所示。

图3.6.7

代码修改完毕后,按F5启动调试,应用程序自动执行,控制台输出结果如下图所示。

图3.6.8

在控制台2中执行命令“vm31”,查看此时应用程序进程的虚拟地址描述符信息;在应用程序释放虚拟页后,可以在控制台2中再次执行命令“vm31”,查看此时应用程序进程的虚拟地址描述符信息。

如下图所示。

图3.6.9

 

四、实验体会

本次实验中,我通过调试EOS操作系统对物理存储空间和虚拟存储空间的分配和回收函数,对操作系统的内存管理机制和实现有了更深一步的认识,并通过调用API函数自己设计了在应用程序进程中分配虚拟页和释放虚拟页的程序。

通过编程,我也捋清了虚拟内存分配和释放时的函数调用关系,并通过阅读函数源码了解了具体的逻辑顺序,也学习到了一些编程的方式。

本次实验同样是一次对于课堂知识的实践,带给我很多启发。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 农林牧渔 > 林学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1