ucore lab3

作者: frans4x | 来源:发表于2019-11-24 16:04 被阅读0次

    OS课程 ucore_lab3实验报告


    练习零:填写已有实验

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

    下面三个, 复制过去就ok
    pmm.c default_pmm.c trap.c
    

    练习1:给未被映射的地址映射上物理页(需要编程)

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

    do_pgfault(){
        ptep = get_pte(mm->pgdir, addr, 1); // 根据引发缺页异常的地址 去找到 地址所对应的 PTE 如果找不到 则创建一页表
        if (*ptep == 0) { // PTE 所指向的 物理页表地址 若不存在 则分配一物理页并将逻辑地址和物理地址作映射 (就是让 PTE 指向 物理页帧)
            if (pgdir_alloc_page(mm->pgdir, addr, perm) == NULL) {
                goto failed;
            }
        } else { // 如果 PTE 存在 说明此时 P 位为 0 该页被换出到外存中 需要将其换入内存
            if(swap_init_ok) { // 是否可以换入页面
                struct Page *page = NULL;
                ret = swap_in(mm, addr, &page); // 根据 PTE 找到 换出那页所在的硬盘地址 并将其从外存中换入
                if (ret != 0) {
                    cprintf("swap_in in do_pgfault failed\n");
                    goto failed;
                }
                page_insert(mm->pgdir, page, addr, perm); // 建立虚拟地址和物理地址之间的对应关系(更新 PTE 因为 已经被换入到内存中了)
                swap_map_swappable(mm, addr, page, 0); // 使这一页可以置换
                page->pra_vaddr = addr; // 设置 这一页的虚拟地址
            }
    }
    

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

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

    可参考lab2

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

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

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

    FIFO 置换算法 因此 每次换出的都应该是 最先进来的 页
    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);
    
        list_add(head, entry); // 就是将这一页加入到链表头中(最近访问过的放前面) 使其可以被置换算法使用到
        return 0;
    }
    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);
    
        list_entry_t *le = head->prev; // 换出最先进来的页 (因为每次访问一个页 都是插入到头节点的后面 因此 头节点的前面就是最先访问的页)
        struct Page* page = le2page(le, pra_page_link); // 和之前一样 通过 le 这个链表节点的地址 减去 pra_page_link 在 Page 结构体中的 Offset 得到 Page 的地址
        list_del(le); // 删掉这个节点
        *ptr_page = page; // 将这一页地址存到 ptr_page 中 给 调用本函数的函数使用
        return 0;
    }
    

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

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

    • 需要被换出的页的特征是什么?
    • 在ucore中如何判断具有这样特征的页?
    • 何时进行换入和换出操作?
    支持
    首选 页表项的 Dirty Bit 为 0 的页 且 Access Bit 为 0 的页 其次是 访问了但没修改的页 最次是 访问了修改了的页
    !(*ptep & PTE_A) && !(*ptep & PTE_D)  没被访问过 也没被修改过
    (*ptep & PTE_A) && !(*ptep & PTE_D) 被访问过 但没被修改过
    !(*ptep & PTE_A) && (*ptep & PTE_D) 没被访问过 但被修改过
    换入是在缺页异常的时候 换出是在物理页帧满的时候
    

    参考:
    [1]https://yuerer.com/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F-uCore-Lab-3/

    相关文章

      网友评论

        本文标题:ucore lab3

        本文链接:https://www.haomeiwen.com/subject/gfblwctx.html