资源

  1. ucore在线实验指导书
  2. 我的ucore实验代码

练习1:给未被映射的地址映射上物理页

题目

完成do_pgfault(mm/vmm.c)函数,给未被映射的地址映射上物理页。设置访问权限的时候需要参考页面所在 VMA 的权限,同时需要注意映射物理页时需要操作内存控制结构所指定的页表,而不是内核的页表。注意:在LAB3 EXERCISE 1处填写代码。执行make qemu后,如果通过check_pgfault函数的测试后,会有“check_pgfault() succeeded!”的输出,表示练习1基本正确。

请在实验报告中简要说明你的设计实现过程。请回答如下问题:

  1. 请描述页目录项(Page Directory Entry) 和页表项(Page Table Entry) 中组成部分对ucore实现页替换算法的潜在用处。
  2. 如果ucore的缺页服务例程在执行过程中访问内存,出现了页访问异常,请问硬件要做哪些事情?

解答

我的设计实现过程

do_pgfault函数已经完成了参数检查及错误检查等流程,根据注释不难完成剩下的流程。

  1. 检查页面异常发生时的错误码的最低两位,即存在位和读/写位,如果发现错误则打印相关提示信息并返回。导致错误的原因有:读没有读权限的内存、写没有写权限的内存、所读内容在内存中却读失败等。(原代码中已实现)

  2. 用虚拟地址addr索引页目录表和页表,得到对应的页表项。这时要分两种情况讨论。

  3. 如果页表项为0,说明系统尚未为虚拟地址addr分配物理页,因此首先需要申请分配一个物理页;然后设置页目录表和页表,以建立虚拟地址addr到物理页的映射;最后,设置该物理页为swappable,并且把它插入到可置换物理页链表的末尾。

  4. 如果页表项不为0,而又出现缺页异常,说明系统已建立虚拟地址addr到物理页的映射,但对应物理页已经被换出到磁盘中。这时同样需要申请分配一个物理页,把换出到磁盘中的那个页面的内容写到该物理页中;接下来和步骤3类似,同样需要建立虚拟地址addr到物理页的映射,同样需要把该物理页插入到可置换页链表的末尾。

问题1:页目录项和页表项对页替换算法的用处

答:页替换涉及到换入换出,换入时需要将某个虚拟地址vaddr对应于磁盘的一页内容读入到内存中,换出时需要将某个虚拟页的内容写到磁盘中的某个位置。而页表项可以记录该虚拟页在磁盘中的位置,为换入换出提供磁盘位置信息。页目录项则是用来索引对应的页表。

问题2:缺页服务例程出现页访问异常时,硬件需要做哪些事情

答:

  1. 关中断
  2. 保护现场。包括:将页访问异常的错误码压入内核栈的栈顶、将导致页访问异常的虚拟地址记录在cr2寄存器中、保存状态寄存器PSW及断点等。
  3. 根据中断源,跳转到缺页服务例程

代码优化

对照答案对代码进行优化。

  1. do_pgfault调用get_pte时没有检查返回值。

    我的代码:
pte_t *ptep = get_pte(mm->pgdir, addr, 1);

答案的代码:

pte_t *ptep=NULL;
// try to find a pte, if pte's PT(Page Table) isn't existed, then create a PT.
// (notice the 3th parameter '1')
if ((ptep = get_pte(mm->pgdir, addr, 1)) == NULL) {
cprintf("get_pte in do_pgfault failed\n");
goto failed;
}
  1. do_pgfault调用pgdir_alloc_page和swap_in失败后没打印错误信息以方便定位。

    我的代码:
    if (*ptep == 0) {
if (page = pgdir_alloc_page(mm->pgdir, addr, perm)) {
ret = 0;
}
}
else if (swap_init_ok) {
swap_in(mm, addr, &page); if (0 == page_insert(mm->pgdir, page, addr, perm)) {
swap_map_swappable(mm, addr, page, 0);
ret = 0;
}
}

答案的代码:

    if (*ptep == 0) { // if the phy addr isn't exist, then alloc a page & map the phy addr with logical addr
if (pgdir_alloc_page(mm->pgdir, addr, perm) == NULL) {
cprintf("pgdir_alloc_page in do_pgfault failed\n");
goto failed;
}
}
else { // if this pte is a swap entry, then load data from disk to a page with phy addr
// and call page_insert to map the phy addr with logical addr
if(swap_init_ok) {
struct Page *page=NULL;
if ((ret = swap_in(mm, addr, &page)) != 0) {
cprintf("swap_in in do_pgfault failed\n");
goto failed;
}
page_insert(mm->pgdir, page, addr, perm);
swap_map_swappable(mm, addr, page, 1);
page->pra_vaddr = addr;
}
else {
cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep);
goto failed;
}
}

练习2:补充完成基于FIFO的页面替换算法(需要编程)

题目

完成vmm.c中的do_pgfault函数,并且在实现FIFO算法的swap_fifo.c中完成map_swappable和swap_out_victim函数。通过对swap的测试。注意:在LAB3 EXERCISE 2处填写代码。执行make qemu后,如果通过check_swap函数的测试后,会有“check_swap() succeeded!”的输出,表示练习2基本正确。

请在实验报告中简要说明你的设计实现过程。

请在实验报告中回答如下问题:

  1. 如果要在ucore上实现"extended clock页替换算法",请给出你的设计方案,现有的swap_manager框架是否足以支持在ucore中实现此算法?如果是,请给出你的设计方案。如果不是,请给出你的新的扩展和基此扩展的设计方案。并需要回答如下问题:

    • 需要被换出的页的特征是什么?
    • 在ucore中如何判断具有这样特征的页?
    • 何时进行换入和换出操作?

解答

我的设计实现过程

练习1中结合do_pgfault函数大致分析了缺页异常处理的流程,但对换入换出只作了简略讨论。这里结合swap_fifo.c的map_swappable和swap_out_victim函数进一步讨论换入换出流程。

  1. 为支持换入换出,在lab 2的基础上主要修改了两个地方:一是当虚拟页被换出到磁盘时,用对应页表项的高24位记录磁盘地址;二是在Page结构体中增加了pra_page_link和pra_vaddr两个字段,前者用于将可换出的物理页保存在一个链表中,后者用于记录当前物理页对应的虚拟页地址(由于可以换入换出,同一个物理页在不同时刻可能被映射到不同的虚拟页,因此有必要增加一个字段记录当前映射到的虚拟页地址)。

  2. map_swappable函数根据FIFO置换算法,将一个物理页添加到可换出物理页链表的末尾,同时更新物理页对应的虚拟页地址。

  3. swap_out_victim函数根据FIFO置换算法,选择可换出物理页链表的首元素,作为将被换出的物理页。

回答问题(待完成)

Challenge 1:实现识别dirty bit的 extended clock页替换算法(待完成)

Challenge 2:实现不考虑实现开销和效率的LRU页替换算法(待完成)

《ucore lab3》实验报告的更多相关文章

  1. [操作系统实验lab3]实验报告

    [感受] 这次操作系统实验感觉还是比较难的,除了因为助教老师笔误引发的2个错误外,还有一些关键性的理解的地方感觉还没有很到位,这些天一直在不断地消化.理解Lab3里的内容,到现在感觉比Lab2里面所蕴 ...

  2. Ucore lab1实验报告

    练习一 Makefile 1.1 OS镜像文件ucore.img 是如何一步步生成的? + cc kern/init/init.c + cc kern/libs/readline.c + cc ker ...

  3. ucore操作系统学习(三) ucore lab3虚拟内存管理分析

    1. ucore lab3介绍 虚拟内存介绍 在目前的硬件体系结构中,程序要想在计算机中运行,必须先加载至物理主存中.在支持多道程序运行的系统上,我们想要让包括操作系统内核在内的各种程序能并发的执行, ...

  4. 《ucore lab1 exercise5》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 题目:实现函数调用堆栈跟踪函数 我们需要在lab1中完成kdebug.c中函数print_stackframe的实现,可以通过函数print_s ...

  5. 《ucore lab8》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1: 完成读文件操作的实现(需要编码) 题目 首先了解打开文件的处理流程,然后参考本实验后续的文件读写操作的过程分析,编写在sfs_inod ...

  6. 《ucore lab7》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1: 理解内核级信号量的实现和基于内核级信号量的哲学家就餐问题(不需要编码) 题目 完成练习0后,建议大家比较一下(可用meld等文件dif ...

  7. 《ucore lab6》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1: 使用 Round Robin 调度算法(不需要编码) 题目 完成练习0后,建议大家比较一下(可用kdiff3等文件比较软件) 个人完成 ...

  8. 《ucore lab5》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1: 加载应用程序并执行(需要编码) 题目 do_execv函数调用load_icode(位于kern/process/proc.c中) 来 ...

  9. 《ucore lab4》实验报告

    资源 ucore在线实验指导书 我的ucore实验代码 练习1:分配并初始化一个进程控制块 题目 alloc_proc函数(位于kern/process/proc.c中) 负责分配并返回一个新的str ...

随机推荐

  1. 建立自己的键盘栈(shortcutkeyStack)

    建立自己的键盘栈(shortcutkeyStack) 作为一名开发者, 快捷键是必不可少的, 并且各种开发工具都有提供快捷键. 但是各种工具(IDE,编辑器)因为历史或者其他不可抗原因(比如键盘的布局 ...

  2. Pyspark 最近使用的一些有趣姿势的梳理

    之前对 SQL 还是不是非常熟悉的,但是现在或多或少还是会写一些计算任务.比如最近在推送将所有天级的耗时任务都从传统关系型数据库迁移至 Spark 集群当中进行计算,中间遇到一些有趣的小问题在这里记录 ...

  3. copy()函数技术推演

    /*** str_copy.c ***/ #include<stdio.h> void copy_str21(char *from, char *to) { for(; *from != ...

  4. 第02组 Alpha冲刺(2/6)

    队名:無駄無駄 组长博客 作业博客 组员情况 张越洋 过去两天完成了哪些任务 任务分配.进度监督 提交记录(全组共用) 接下来的计划 沟通前后端成员,监督.提醒他们尽快完成各自的进度 还剩下哪些任务 ...

  5. C# 使用大漠插件, 源码在Github和码云 ..希望对大家有所帮助

    c# 使用大漠插件. 完成 类似 按键精灵的 功能. 方法 注释 正在慢慢的 完善中 目录 仓库 github 码云 准备 效果图 如何运行 1. 注册 大漠dll 到com (资源在 源码 DLL ...

  6. Linux 修改时区的办法

    Linux修改时区的正确方法 CentOS和Ubuntu的时区文件是/etc/localtime,但是在CentOS7以后localtime以及变成了一个链接文件 [root@centos7 ~]# ...

  7. [spring-boot] 健康状况监控

    pom文件 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>s ...

  8. MITMProxy如何配置二次代理

    MITMProxy如何配置二次代理 0.2172018.09.05 11:13:15字数 232阅读 2609 前序: mitmproxy真的很强大,或许是大家都各自使用,或者没有相关的需求,导致我废 ...

  9. 【内功修炼】"裁员潮",“中年危机”,该如何战胜你的焦虑

    "裁员"."中年危机"这些曾经看上去比较遥远的词汇,最近开始频繁出现在各种文章和新闻中,个人觉得这主要由两方面原因造成: 近两年,国内外经济形势严峻(更有经济学 ...

  10. ActiveMQ参数异常 “Invalid broker URI”

    某次启动项目报错,提示ActiveMQ参数异常 该参数的值配置如下 跟踪读取配置的代码如下,可以看到读取我配置的key为xmq.actmq.connection.url.forSend的对应值,赋值到 ...