Lab3实验报告

  • Lab3实验报告

    • 练习0填写以有实验
    • 练习1给未被映射的地址映上物理页
      • 问题回答
    • 练习2补充完成基于FIFO的页面替换算法
      • 问题回答
      • 实验运行截图
    • 扩展练习 Challenge

借助于页表机制和实验一涉及的中断异常处理机制,完成PageFault异常处理和FIFO算法的实现,结合磁盘提供的缓存空间,从而能够支持虚存管理。


练习0:填写以有实验

  • 做的实验1/2的代码填入本实验中代码中有“LAB1”,“LAB2”的注释相应部分。

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

设置访问权限的时候需要参考页面所在的VMA的权限,映射物理页时需要操作内存控制结构所指定的页表,不是内核的页表。
启动分页机制后,如果一条指令或数据的虚拟地址所对应的物理页不在内存中,或者访问权限不够,就会产生页错误异常。


1.页表全为0–虚拟地址与物理地址未建立映射关系或者关系撤销
2.物理页不在内存中,需要进行换页机制
3.访问权限不够,报错

  • do_pgfault(mm/vmm.c)
//try to find a vma which include addr
// mm->mmap_cache = NULL;
//     mm->pgdir = NULL;//   mm->map_count = 0;// if (swap_init_ok) swap_init_mm(mm);// else mm->sm_priv = NULL;
struct vma_struct *vma = find_vma(mm, addr);//pagefault_num的初始值为0
pgfault_num++;/*
the virtual continuous memory area(vma)
struct vma_struct {
struct mm_struct *vm_mm; // the set of vma using the same PDT
uintptr_t vm_start;      //    start addr of vma
uintptr_t vm_end;        // end addr of vma
uint32_t vm_flags;       // flags of vma
list_entry_t list_link;  // linear list link which sorted by start addr of vma
};*/
//尝试获得页表入口
if ((ptep = get_pte(mm->pgdir, addr, 1)) == NULL) {cprintf("get_pte in do_pgfault failed\n");goto failed;
}
//页表不存在,页表项全为0
if (*ptep == 0) { // if the phy addr isn't exist, then alloc a page & map the phy addr with logical addr//perm设置权限//尝试申请一个页,如果申请失败,就是内存不足了,退出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 addrif(swap_init_ok) {struct Page *page=NULL;//根据mm结构和addr地址,尝试将硬盘中的内容换入page中,此时page还没有加入到队列中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);}else {cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep);goto failed;}
}
ret = 0;
failed:
return ret;

问题回答

  • 述页目录项(Pag Director Entry)和页表(Page Table Entry)中组成部分对ucore实现页替换算法的潜在用处。

  • 如果ucore的缺页服务例程在执行过程中访问内存,出现了页访问异常,请问硬件要做哪些事情?
    CPU会把产生异常的线性地址存储在CR2中,并且把表示页访问异常类型的值(简称页访问异常错误码,errorCode)保存在中断栈中。

[提示]页访问异常错误码有32位。位0为1表示对应物理页不存在;位1为1表示写异常(比如写了只读页;位2为1表示访问权限异常(比如用户态程序访问内核空间的数据)

[提示] CR2是页故障线性地址寄存器,保存最后一次出现页故障的全32位线性地址。CR2用于发生页异常时报告出错信息。当发生页异常时,处理器把引起页异常的线性地址保存在CR2中。操作系统中对应的中断服务例程可以检查CR2的内容,从而查出线性地址空间中的哪个页引起本次异常。
产生页访问异常后,CPU硬件和软件都会做一些事情来应对此事。首先页访问异常也是一种异常,所以针对一般异常的硬件处理操作是必须要做的,即CPU在当前内核栈保存当前被打断的程序现场,即依次压入当前被打断程序使用的EFLAGS,CS,EIP,errorCode;由于页访问异常的中断号是0xE,CPU把异常中断号0xE对应的中断服务例程的地址(vectors.S中的标号vector14处)加载到CS和EIP寄存器中,开始执行中断服务例程。这时ucore开始处理异常中断,首先需要保存硬件没有保存的寄存器。在vectors.S中的标号vector14处先把中断号压入内核栈,然后再在trapentry.S中的标号__alltraps处把DS、ES和其他通用寄存器都压栈。自此,被打断的程序执行现场(context)被保存在内核栈中。接下来,在trap.c的trap函数开始了中断服务例程的处理流程,大致调用关系为:

trap–> trap_dispatch–>pgfault_handler–>do_pgfault
产生页访问异常后,CPU把引起页访问异常的线性地址装到寄存器CR2中,并给出了出错码errorCode,说明了页访问异常的类型。ucore OS会把这个值保存在struct trapframe 中tf_err成员变量中。而中断服务例程会调用页访问异常处理函数do_pgfault进行具体处理。这里的页访问异常处理是实现按需分页、页换入换出机制的关键之处。

ucore中do_pgfault函数是完成页访问异常处理的主要函数,它根据从CPU的控制寄存器CR2中获取的页访问异常的物理地址以及根据errorCode的错误类型来查找此地址是否在某个VMA的地址范围内以及是否满足正确的读写权限,如果在此范围内并且权限也正确,这认为这是一次合法访问,但没有建立虚实对应关系。所以需要分配一个空闲的内存页,并修改页表完成虚地址到物理地址的映射,刷新TLB,然后调用iret中断,返回到产生页访问异常的指令处重新执行此指令。如果该虚地址不在某VMA范围内,则认为是一次非法访问。

练习2:补充完成基于FIFO的页面替换算法

vmm.c的do_pgfault

   if(swap_init_ok) {struct Page *page=NULL;//根据mm结构和addr地址,尝试将硬盘中的内容换入page中,此时page还没有加入到队列中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);}else {cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep);goto failed;}

swap _fifo.c

static int
_fifo_map_swappable(struct mm_struct *mm, uintptr_t addr, struct Page *page, int swap_in)
{
list_entry_t *head=(list_entry_t*) mm->sm_priv;
list_entry_t *entry=&(page->pra_page_link);assert(entry != NULL && head != NULL);
//record the page access situlation
/*LAB3 EXERCISE 2: 2013011424*/
//(1)link the most recent arrival page at the back of the pra_list_head qeueue.
//将最近使用的页面添加到次序的队尾
list_add(head, entry);
return 0;}

_ fifo _ swap_out _victim

static int
_fifo_swap_out_victim(struct mm_struct *mm, struct Page ** ptr_page, int in_tick)
{list_entry_t *head=(list_entry_t*) mm->sm_priv;assert(head != NULL);assert(in_tick==0);/* Select the victim *//*LAB3 EXERCISE 2: 2013011424*/ //(1)  unlink the  earliest arrival page in front of pra_list_head qeueue//(2)  set the addr of addr of this page to ptr_page/* Select the tail */
//用le指示需要被换出的页list_entry_t *le = head->prev;assert(head!=le);
//le2page 宏可以根据链表元素,获得对应page的指针struct Page *p = le2page(le, pra_page_link);
//将最早进来的页面从队列中删除list_del(le);assert(p !=NULL);
//将这一页的地址存储在ptr_page中*ptr_page = p;return 0;
}

问题回答

  • 如果要在ucore上实现”extended clock页替换算法”请给你的设计方案,现有的swap_manager框架是否足以支持在ucore中实现此算法?如果是,请给你的设计方案。如果不是,请给出你的新的扩展和基此扩展的设计方案。并需要回答如下问题
    需要被换出的页的特征是什么?
    在ucore中如何判断具有这样特征的页?
    何时进行换入和换出操作?

实验运行截图

扩展练习 Challenge

  • 现识别dirty bit的 extended clock页替换算法
    根据页面近期是否被修改从而决定页面是否被换出,在查询空闲页时加上对dirty bit的判断。

操作系统淘汰页面时,对当前指针指向的页所对应的页表项进行查询,如果dirty bit为0,把页换到硬盘上,如果dirty bit 为1,则将dirty bit改为0,继续访问下一页

编写_extend_clock()然后更改默认替换算法.

mm/swap_fifo.c

struct swap_manager swap_manager_fifo =
{.name            = "fifo swap manager",.init            = &_fifo_init,.init_mm         = &_fifo_init_mm,.tick_event      = &_fifo_tick_event,.map_swappable   = &_fifo_map_swappable,.set_unswappable = &_fifo_set_unswappable,
// .swap_out_victim = &_fifo_swap_out_victim,
//更改默认的算法
.swap_out_victim = &_extended_clock_swap_out_victim,.check_swap      = &_fifo_check_swap,
};

在mm/swap_fifo.c添加函数

static int _extended_clock_swap_out_victim(struct mm_struct*mm,struct Page **ptr_page,int in_tick)
{
list_entry_t*head=(list_entry_t*)mm->sm_priv;
assert(head!=NULL);
assert(in_tick==0);list_entry_t*le=head->prev;
assert(head!=le);
while(le!=head)
{struct Page*p=le2page(le,pra_page_link);//获取页表项pte_t*ptep=get_pte(mm->pgdir,p->pra_vaddr,0);//判断获得的页表项是否正确if(*ptep<0x1000){break;}if(!(*ptep&PTE_D)){//如果dirty bit 为0,换出页面,将页面从队列中删除list_del(le);assert(p!=NULL);//将这一个页放在ptr_page中*ptr_page=p;return 0;}else{//如果为1 ,赋值为0跳过*ptep&=0xffffffbf;}le=le->prev;
}
le=head->prev;
assert(head!=le);
struct Page*p=le2page(le,pra_page_link);list_del(le);
assert(p!=NULL);*ptr_page=p;
return 0;

}

ucore lab3实验报告相关推荐

  1. ucore lab1 实验报告

    UCORE LAB1 实验报告 练习一 理解通过make生成执行文件的过程 1.操作系统镜像文件ucore.img是如何一步一步生成的? 先打开lab1文件夹下的Makefile,查看里面的代码,在各 ...

  2. HIT 软件构造 lab3实验报告

    2020年春季学期 计算机学院<软件构造>课程 Lab 3实验报告 姓名 赵旭东 学号 1180300223 班号 1803002 电子邮件 1264887178@qq.com 手机号码 ...

  3. 操作系统ucore lab1实验报告

    操作系统lab1实验报告 [练习1] 理解通过 make 生成执行文件的过程.(要求在报告中写出对下述问题的回答) 在此练习中,大家需要通过阅读代码来了解: 1. 操作系统镜像文件 ucore.img ...

  4. [HITSC]哈工大2020春软件构造Lab3实验报告

    Github地址 1 实验目标概述 本次实验覆盖课程第 3.4.5 章的内容,目标是编写具有可复用性和可维护 性的软件,主要使用以下软件构造技术: 子类型.泛型.多态.重写.重载 继承.代理.组合 常 ...

  5. BUAA OS LAB3 实验报告

    Thinking3.1 我们用两部分标识一个进程,分别为ASID和其对应进程控制块在进程数组中的位置,使用e = envs + ENVX(envid)并未对ASID部分进行检查,可能出现"前 ...

  6. 操作系统实验报告11:ucore Lab 2

    ucore实验报告2 实验内容 uCore Lab 2:物理内存管理 (1) 编译运行 uCore Lab 2 的工程代码: (2) 完成 uCore Lab 2 练习 1-3 的编程作业: (3) ...

  7. 操作系统实验报告1:ucore Lab 1

    操作系统实验报告1 实验内容 阅读 uCore 实验项目开始文档 (uCore Lab 0),准备实验平台,熟悉实验工具. uCore Lab 1:系统软件启动过程 (1) 编译运行 uCore La ...

  8. 《ucore lab1 练习5》实验报告

    [练习5]实现函数调用堆栈跟踪函数 我们需要在lab1中完成kdebug.c中函数print_stackframe的实现,可以通过函数print_stackframe来跟踪函数调用堆栈中记录的返回地址 ...

  9. 《ucore lab1 exercise5》实验报告

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

最新文章

  1. Jquery_操作cookies
  2. 基于VLC的播放器开发
  3. qpython手机版-qpythonl app下载
  4. angular组件-特殊的瀑布流(原创)
  5. HALCON示例程序check_fish_stick_dimension.hdev生鱼棒尺寸测量;基于形态学的像素级精度尺寸测量
  6. mysql分组查询的两类
  7. SCOPE_IDENTITY和@@identity的区别
  8. ConvLab介绍及使用
  9. 形态学滤波:(1)腐蚀与膨胀 (2)开运算,闭运算,形态学梯度,顶帽,黑帽...
  10. (21)System Verilog按时间顺序的通知需求(变量驱动)
  11. 趋势程序大赛第 六七 天
  12. 再见!公司的烂系统……
  13. 使用HealthKit过程中遇到的坑
  14. matlab人脸重建,3D人脸重建: BFM结合表情模型
  15. 精心整理!最全的100个Python精选库,建议收藏!
  16. Unity进度条制作
  17. 关于python数字的一种下划线奇怪写法
  18. python中key=lambda_排序后的语法(key=lambda:…)
  19. 对青浦区专利工作试点和示范企业给予20万元和30万元资助
  20. android 获取文件大小

热门文章

  1. Android一款UI体验好于NumberPicker的自定义控件NumberPickerView
  2. java hprof 分析_[转]Sun JDK自带JVM内存使用分析工具HProf
  3. 网易云音乐api400 Bad Request
  4. Linux项目部署单体项目全流程
  5. 早报八点半:5月12日Web3加密行业每日新闻汇总
  6. uln2003和2803两个有刷直流电机控制方案
  7. php ng 性能,PHP NG (PHP 5.7) 性能比PHP5.6 提升近1倍_PHP
  8. 《ありがとう》中文名《感谢》
  9. Fuzzing101:Exercise 1 - Xpdf 翻译+解题
  10. Mybatis:使用Map接收结果时别名驼峰无效