ucore lab3(虚拟内存管理)
一、实验目的
1.1了解虚拟内存的Page Fault异常处理实现
1.2了解页替算法在操作系统中的实现
二、实验内容
本次实验是在实验二的基础上,借助于页表机制和实验一中涉及的中断异常处理机制,完成Page Fault异常处理和FIFO页替换算法的实现,结合磁盘提供的缓存空间,从而能够支持虚存管理,提供一个比实际物理内存空间“更大”的虚拟内存空间给系统使用。这个实验与实际操作系统中的实现比较起来要简单,不过需要了解实验一和实验二的具体实现。实际操作系统系统中的虚拟内存管理设计与实现是相当复杂的,涉及到与进程管理系统、文件系统等的交叉访问。如果大家有余力,可以尝试完成扩展练习,实现extended clock页替换算法。
三、实验步骤及流程
3.0 练习0:填写已有实验
本实验依赖实验1/2。请把你做的实验1/2的代码填入本实验中代码中有“LAB1”,“LAB2”的注释相应部分。
3.1 练习1:给未被映射的地址映射上物理页(需要编程)
3.1.1实验要求
完成do_pgfault(mm/vmm.c)函数,给未被映射的地址映射上物理页。设置访问权限 的时候需要参考页面所在 VMA 的权限,同时需要注意映射物理页时需要操作内存控制 结构所指定的页表,而不是内核的页表。注意:在LAB3 EXERCISE 1处填写代码。执行“make qemu”后,如果通过check_pgfault函数的测试后,会“check_pgfault() succeeded!”的输出,表示练习1基本正确。
请在实验报告中简要说明你的设计实现过程。请回答如下问题:
·请描述页目录项(Page Directory Entry)和页表项(Page Table Entry)中组成部分对ucore实现页替换算法的潜在用处。
·如果ucore的缺页服务例程在执行过程中访问内存,出现了页访问异常,请问硬件要做哪些事情?
3.1.2关键数据结构及知识点
(1)有关虚拟内存需要注意:
①虚拟内存单元不一定有实际的物理内存单元对应,即实际的物理内存单元可能不存在;
②如果虚拟内存单元对应有实际的物理内存单元,那二者的地址一般是不相等的;
③通过操作系统实现的某种内存映射可建立虚拟内存与物理内存的对应关系,使得程序员或CPU访问的虚拟内存地址会自动转换为一个物理内存地址。
(2)当启动分页机制以后,如果一条指令或数据的虚拟地址所对应的物理页框不在内存中或者访问的类型有错误(比如写一个只读页或用户态程序访问内核态的数据等),就会发生页错误异常。产生页面异常的原因有:
①目标(虚拟)页面不存在(页表项全为0,即该线性地址与物理地址尚未建立映射或者已经撤销),此时应该直接报错;
②相应的物理页面不在内存中(页表项非空,但Present标志位=0,比如在swap分区或磁盘文件上),此时应该建立映射虚拟页和物理页的映射关系;
③目标访问页的权限不符合(此时页表项P标志=1,比如企图写只读页面),此时应该直接报错。
当出现上面情况之一,那么就会产生页面page fault(#PF)异常。产生异常的线性地址(虚拟地址)存储在 CR2中,并且将是page fault的产生类型保存在error code中。
(3)虚拟地址空间和物理地址空间

一块虚拟地址(vma)可能映射到一个或多个多个物理页。由于一开始,分配虚拟空间超过了物理空间的大小,比如在上图中只有5个物理页帧,但其实我们给它分了7个虚拟页,那很明显一定会有两个虚拟页没有对应的物理页帧。那么如果访问到这两个虚拟页,在二级页表里面它会没有对应映射关系,一旦没有对应映射关系,那就会产生缺页异常,因此就是do_pgfault函数的实现功能,它要建立这个映射关系。
(4)do_pgfault()的调用关系

(5)虚拟内存块空间(vma,kern/mm/vmm.h)
struct vma_struct {
struct mm_struct *vm_mm; // 指向一个比vma_struct更高的抽象层次的数据结构mm_struct
uintptr_t vm_start; // vma的开始地址
uintptr_t vm_end; // vma的结束地址
uint32_t vm_flags; // 虚拟内存空间的属性
list_entry_t list_link; // 双向链表,按照从小到大的顺序把虚拟内存空间链接起来
};
VMA数据结构,用于管理应用程序的虚拟内存,更准确来说,VMA是描述应用程序对虚拟内存“需求”的结构,它包含五个成员:
①mm:是一个更高级更抽象的数据结构,代表整个应用程序所用到的所有VMA(该VMA的占有程序),接下来马上讨论。
②vm_start、vm_end:描述一个合理的地址空间范围(确保 vm_start < vm_end的关系);
③vm_flags:该虚拟内存空间的属性,目前的属性包括可读、可写、可执行;
④list_link:一个双向链表,按照从小到大的顺序把一系列用vma_struct表示的虚拟内存空间链接起来,并且还要求这些链起来的vma_struct应该是不相交的,即vma之间的地址空间无交集。
(6)应用程序映射到的虚拟空间块综述结构(mm,kern/mm/vmm.h)
struct mm_struct {
list_entry_t mmap_list; // 双向链表头,链接了所有属于同一页目录表的虚拟内存空间
struct vma_struct *mmap_cache; // 指向当前正在使用的虚拟内存空间
pde_t *pgdir; //指向的就是 mm_struct数据结构所维护的页表
int map_count; //记录mmap_list里面链接的vma_struct的个数
void *sm_priv; //指向用来链接记录页访问情况的链表头
如果说vma描述和管理的是一系列虚拟内存块结构,那么mm则用来描述,究竟是哪个应用程序使用了这些vma,它们是通过vma中的成员mm联系在一起的。mm也有五个成员,分别解释如下:
①list_entry_t mmap_list:双向链表,链接了所有属于同一页目录表的虚拟内存空间;
②struct vma_struct *mmap_cache:指向当前正在使用的虚拟内存空间;
③pde_t *pgdir:指向的mm_struct数据结构所维护的一级页表,每个应用程序都有页表,那么这里指向应用程序正在操作的那个;
④int map_count:记录mmap_list里链接的vma_struct的个数(该程序用了多少个虚拟页);
⑤void *sm_priv:指向用来链接记录页访问情况的链表头。用于FIFO替换策略的访问。
3.1.3代码实现(do_pgfault函数的实现(kern/vmm.c))
do_pgfault(struct mm_struct *mm, uint32_t error_code, uintptr_t addr) {
int ret = -E_INVAL;
//try to find a vma which include addr尝试寻找包括addr的vma
struct vma_struct *vma = find_vma(mm, addr);
pgfault_num++;
//If the addr is in the range of a mm's vma?
if (vma == NULL || vma->vm_start

本文介绍了ucorelab3实验,旨在实现虚拟内存管理。实验包括PageFault异常处理和FIFO页替换算法的实现,支持虚拟内存管理。文章详细讲解了实验步骤、关键数据结构及代码实现,并探讨了如何实现extended clock页替换算法。
最低0.47元/天 解锁文章
5628





