if (!(ptep = get_pte(mm->pgdir, addr, 1))) goto failed; //(1) try to find a pte, if pte's PT(Page Table) isn't existed, then create a PT. if (*ptep == 0) { if (!pgdir_alloc_page(mm->pgdir, addr, perm)) goto failed; //(2) if the phy addr isn't exist, then alloc a page & map the phy addr with logical addr } else { // Exercise 2 }
ret = 0; failed: return ret; }
启动分页机制以后,当程序尝试访问一个不在物理内存中的页帧或是访问权限有错的时候,会触发 CPU 的页面异常(Page Fault),进入中断处理程序。do_pgfault 的作用就是负责处理页面错误。
if(swap_init_ok) { structPage *page=NULL; swap_in(mm, addr, &page); //(1)According to the mm AND addr, try to load the content of right disk page // into the memory which page managed. page_insert(mm->pgdir, page, addr, perm); //(2) According to the mm, addr AND page, setup the map of phy addr <---> logical addr swap_map_swappable(mm, addr, page, 1); //(3) make the page swappable. page->pra_vaddr = addr; } else { cprintf("no swap_init_ok but ptep is %x, failed\n",*ptep); goto failed; }
staticint _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: YOUR CODE*/ //(1)link the most recent arrival page at the back of the pra_list_head qeueue. list_add_before(head, entry); return0; }
staticint _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: YOUR CODE*/ //(1) unlink the earliest arrival page in front of pra_list_head qeueue list_entry_t *first = head->next; //(2) assign the value of *ptr_page to the addr of this page structPage* page = le2page(first, pra_page_link); *ptr_page = page; list_del(first); return0; }