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

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
操作系统实验
院(系) : 计算机科学与技术学院 研究所: 软件与数据科学研究所 教 师: 王红滨
1
主要内容
1.实验目的 2.分页管理物理存储器 3.“pm”命令的源代码 4.虚拟地址描述符及Vm命令 5.分配虚拟页和释放虚拟页的函数
2
1.实验目的
• 通过查看物理存储器的使用情况,并练习 分配和回收物理内存,从而掌握物理存储 器的管理方法。 • 通过查看进程逻辑地址空间的使用情况, 并练习分配和回收虚拟内存,从而掌握进 程逻辑地址空间的管理方法。
“pm”命令执行的结果
12
4.虚拟地址描述符 及Vm命令 整页分配 虚拟地址描述符管理
进程的4G虚拟地址空间
0x00000000 不可访问的64KB缓冲区域。用于捕捉对空 指针的非法访问。 0x00010000 用户进程可用的虚拟地址空间。 用户进程的可执行映像被加载到地址 0x400000处,用户进程的堆和栈也位于这 段区域内。 用户进程调用VirtualAlloc函数进行虚拟 内存分配时,也是在这段区域分配。 0x7FFF0000 不可访问的64KB缓冲区域。用于捕捉对空 指针的非法访问。 0x80000000 物理内存的约1/8被映射到此处,映射的总 量不超过256MB,且向上4M地址对齐。 被映射的物理内存使用如下: 0-64KB:用作I/O缓冲区。 64KB-640KB:用于加载kernel.dll。 640KB-1MB:BIOS区域,不可用。 1MB-?:用于页框号数据库,大小根据 物理页面数量而定。 ?-?:系统内存池。 ?-?:最后8K用作ISR专用栈。 0x90000000
7
3.“pm”命令的源代码 (显示当前物理页的使用情况)
// 输出物理页数量和物理内存数量(以字节为单位) fprintf(StdHandle, "Page Count: %d.\n", MiTotalPageFrameCount); fprintf(StdHandle, "Memory Count: %d * %d = %d Byte.\n", MiTotalPageFrameCount, PAGE_SIZE, MiTotalPageFrameCount * PAGE_SIZE); // 输出零页数量和空闲页数量 fprintf(StdHandle, "\nZeroed Page Count: %d.\n", MiZeroedPageCount); fprintf(StdHandle, "Free Page Count: %d.\n", MiFreePageCount);
STATUS MiAllocateAnyPages(//分配物理页 IN ULONG_PTR NumberOfPages,//要申请的物理页个数 OUT PULONG_PTR PfnArray//返回分配好的物理页框号 )
STATUS MiAllocateZeroedPages(//从0页中分配物理页 IN ULONG_PTR NumberOfPages, OUT PULONG_PTR PfnArray )
} // 统计虚拟页框总数、已分配的虚拟页框和未分配的虚拟页框 TotalVpnCount = pVadList->EndVpn - pVadList->StartingVpn + 1; fprintf(StdHandle, "\nTotal Vpn Count: %d.\n", TotalVpnCount); fprintf(StdHandle, "Allocated Vpn Count: %d.\n", AllocatedVpnCount); FreeVpnCount = TotalVpnCount - AllocatedVpnCount; fprintf(StdHandle, "Free Vpn Count: %d.\n", FreeVpnCount);
用户地址空间 (低2G)
按照请求的大小分配
保留未用
整页分配 虚拟地址描述符管理
0xA0000000 供系统动态管理分配的虚拟地址空间,这 段区域的大小为物理内存大小的1/4,最大 512MB。 这段区域在初始化时,需全部安装PTE,避 免各进程的页目录项不一致。 0xC0000000 0xC0400000 进程页表被映射到此4MB区域。 页表有效PTE计数器被映射到此4KB区域。
3
2.分页管理物理存储器
4
使用页框号数据库管理物理页
typedef struct _MMPFN { ULONG Unused : 9; ULONG PageState : 3; ULONG Next : 20; }MMPFN, *PMMPFN;
// 未用 // 物理页的状态 // 下一个物理页的页框号
16
“vm”命令执行的结果
系 统 进 程
用 户 进 程
17
5.分配虚拟页和释放虚拟页的内核函数
STATUS MmAllocateVirtualMemory( IN OUT PVOID *BaseAddress,//需要分配的基址 IN OUT PSIZE_T RegionSize, //分配区大小,以4K对齐 IN ULONG AllocationType, //虚拟页,物理页 IN BOOL SystemVirtual//用户区还是系统区分配 ) STATUS MmFreeVirtualMemory( IN OUT PVOID *BaseAddress, IN OUT PSIZE_T RegionSize,//为0 IN ULONG FreeType,//MEM_DECOMMIT为只释放物理 页,MEM_RELEASE为虚拟地址和物理页都释放 IN BOOL SystemVirtual )
typedef enum _PAGE_STATE { ZEROED_PAGE, // 零页 FREE_PAGE, // 自由页 BUSY_PAGE, // 占用页 } PAGE_STATE;
5
页框号数据库与物理页的关系
6
与页框号数据库相关的源代码
// 页框号数据库在内核地址空间中的位置(虚拟4G地址空间) #define PFN_DATABASE ((PMMPFN)0x80100000) // 得到页框号对应的页框号数据库项。 #define MiGetPfnDatabaseEntry(pfn) (PFN_DATABASE + pfn) // 物理页总数量。 ULONG_PTR MiTotalPageFrameCount; // 零页链表头以及零页数量。 ULONG_PTR MiZeroedPageListHead; ULONG_PTR MiZeroedPageCount; // 空闲页链表头以及空闲页数量。 ULONG_PTR MiFreePageListHead; ULONG_PTR MiFreePageCount;
内核地址空间 (高2G)
0xC0401000 系统PTE区域,用于快速将单个物理页框映 射至此,对物理内存进行初始化。 0xC0800000 保留未用
13
虚拟地址描述符及描述符链表
// 虚拟地址描述符 typedef struct _MMVAD{ ULONG_PTR StartingVpn;//开始虚拟页框号 ULONG_PTR EndVpn; //结束虚拟页框号 LIST_ENTRY VadListEntry; //链表项 }MMVAD, *PMMVAD; // 虚拟地址描述符链表 typedef struct _MMVAD_LIST{ ULONG_PTR StartingVpn; //开始虚拟页框号 ULONG_PTR EndVpn; //结束虚拟页框号 LIST_ENTRY VadListHead; //链表头 }MMVAD_LIST, *PMMVAD_LIST; 14
// 输出已使用的物理页数量 fprintf(StdHandle, "\Hale Waihona Puke BaiduUsed Page Count: %d.\n", MiTotalPageFrameCount MiZeroedPageCount - MiFreePageCount);
8
“pm”命令执行的结果
9
分配物理页与释放物理页的函数
系统进程的Vad链表举例
15
“vm”命令的源代码
// 获得指定进程的 VAD 链表 …… // 输出 VAD 链表中记录的起始页框号,结束页框号 fprintf(StdHandle, "Total Vpn from %d to %d. (0x%X - 0x%X)\n\n", pVadList->StartingVpn, pVadList->EndVpn, pVadList->StartingVpn * PAGE_SIZE, (pVadList->EndVpn + 1) * PAGE_SIZE - 1); // 遍历 VAD 链表,输出所有 VAD 的起始页框号,结束页框号和包含的虚拟页框数量 Index = AllocatedVpnCount = 0; for(pListEntry = pVadList->VadListHead.Next; pListEntry != &pVadList->VadListHead; pListEntry = pListEntry->Next) { Index++; //根据结构体某个域的地址反推结构体的地址 pVad = CONTAINING_RECORD(pListEntry, MMVAD, VadListEntry); VpnCount = pVad->EndVpn - pVad->StartingVpn + 1; fprintf(StdHandle, "%d# Vad Include %d Vpn From %d to %d. (0x%X - 0x%X)\n", Index, VpnCount, pVad->StartingVpn, pVad->EndVpn, pVad->StartingVpn * PAGE_SIZE, (pVad->EndVpn + 1) * PAGE_SIZE - 1); AllocatedVpnCount += VpnCount;
// 分配一个物理页 MiAllocateAnyPages(1, PfnArray); fprintf(StdHandle, "\n****** After Allocate One Page ******\n"); fprintf(StdHandle, "Zeroed Page Count: %d.\n", MiZeroedPageCount); fprintf(StdHandle, "Free Page Count: %d.\n", MiFreePageCount); fprintf(StdHandle, "Used Page Count: %d.\n", MiTotalPageFrameCount MiZeroedPageCount - MiFreePageCount); // 然后再释放这个物理页 MiFreePages(1, PfnArray); fprintf(StdHandle, "\n****** After Free One Page ******\n"); fprintf(StdHandle, "Zeroed Page Count: %d.\n", MiZeroedPageCount); fprintf(StdHandle, "Free Page Count: %d.\n", MiFreePageCount); fprintf(StdHandle, "Used Page Count: %d.\n", MiTotalPageFrameCount -11 MiZeroedPageCount - MiFreePageCount);
STATUS MiFreePages(//释放物理页 IN ULONG_PTR NumberOfPages, //释放物理页个数 IN PULONG_PTR PfnArray//释放物理页的页框号 )
10
在“pm”命令中分配、释放物理页 (添加之后变化) ULONG_PTR PfnArray[1];
相关文档
最新文档