ucore-lab3 实验报告

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

1、描述:  

lab2中我们实现并启动了分页机制,现在我们需要考虑什么情况下会产生页错误异常并触发中断。显答案是在指令或数据的虚拟地址所对应的物理页不在内存中,或者访问权限不够的情况下。其具体原因有以下三点:  

①页表项全为0——虚拟地址与物理地址未建立映射关系或已被撤销。 

②物理页面不在内存中——需要进行换页机制。 

③访问权限不够——输出错误信息,并退出。  

根据以上三点错误原因,完成页错误处理函数do_pgfault()。  

2思路:  

do_pgfault()函数从CR2寄存器中获取页错误异常的虚拟地址,根据error code来查找这个虚拟地址是否在某一个VMA的地址范围内,并且具有正确的权限。如果满足上述两个要求,则需要为分配一个物理页。 

3、实现

//页表项非空,可以尝试换入页面     
else{           
    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; 
    }    
}   



 

练习二:补充完成基于FIFO()的页面替换算法。  

1、描述:    

在上面的练习中,页错误异常发生时,有可能是因为页面保存在swap区或者磁盘文件上造成的,练习二需要利用页面替换算法解决这个问题。 

2思路:  

页面替换主要分为两个方面,页面换出和页面换入。页面换入主要在vmm.c中的do_pgfault()函数实现;页面换出主要在swap_fifo.c中的swap_out_vistim()函数实现。    在换入时,需要先检查产生访问异常的地址是否属于某个vma表示的合法虚 拟地址,并且保存在硬盘的swap文件中(对应的PTE的高24位不为0)。如果满足以上亮点,则执行swap_in() 函数换入页面。  

换出则相对简单,当申请空闲页面时,alloc_pages()函数不能获得空闲页,则直接调用swap_out()函数换出不常用的页面。  

3、实现:  

(一)、页面换入的实现 

//页表项非空,可以尝试换入页面     
else{           
    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; 
    }    
}   




(二)、页面换出的关键代码  

FIFO替换算法会维护一个队列,队列按照页面调用的次序排列,越早被加载到内存的页面会越早被换出。下面几个关键函数在swap_out()中被调用。    

①_fifo_map_swappable()函数将最近被用到的页面添加到算法所维护的次序队列  

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; 
} 


②_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);
    //用le指示需要被换出的页         
    list_entry_t *le = head->prev;      
    assert(head!=le);  
    //le2page宏可以根据链表元素获得对应的Page指针p
    struct Page *p = le2page(le, pra_page_link);      
    //将进来最早的页面从队列中删除      
    list_del(le);      
    assert(p !=NULL);       
    //将这一页的地址存储在ptr_page中      
    *ptr_page = p;      
    return 0; 
}




结果部分截图: 


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值