JOS2-3

我们来琢磨下,下面这个函数应该怎么实现:

// Given 'pgdir', a pointer to a page directory, pgdir_walk returns
// a pointer to the page table entry (PTE) for linear address 'va'.
// This requires walking the two-level page table structure.
//
// The relevant page table page might not exist yet.
// If this is true, and create == false, then pgdir_walk returns NULL.
// Otherwise, pgdir_walk allocates a new page table page with page_alloc.
//    - If the allocation fails, pgdir_walk returns NULL.
//    - Otherwise, the new page's reference count is incremented,
//    the page is cleared,
//    and pgdir_walk returns a pointer into the new page table page.
//
// Hint 1: you can turn a Page * into the physical address of the
// page it refers to with page2pa() from kern/pmap.h.
//
// Hint 2: the x86 MMU checks permission bits in both the page directory
// and the page table, so it's safe to leave permissions in the page
// more permissive than strictly necessary.
//
// Hint 3: look at inc/mmu.h for useful macros that mainipulate page
// table and page directory entries.
//  #返回值带属性
pte_t *
pgdir_walk(pde_t *pgdir, const void *va, int create)
{
    // Fill this function in

}

要求:

返回值为指向PTE的指针

pte_t *
pgdir_walk(pde_t *pgdir, const void *va, int create)
{
    pde_t pt_base_attr;
    pte_t pt_base;
    struct PageInfo *pp;
    pde_t new_pt_base;

    // #首先从页目录中取PDE
    pt_base_attr = pgdir[PDX(va)];
    // #PDE实质就是 PT的基址|属性
    // #去掉属性 获取基址
    pt_base = (pte_t)(pt_base_attr & 0xfffff000)
    if(pt_base){
    // #如果为真 返回PTE的地址
        return &pt_base[PTX(va)];
    }
    else{
        if(create == false){
            return NULL;
        }
        // #如果PDE为0 那么申请一个PT
        pp = page_alloc(1);

        if(!pp){
            return NULL;
        }
        new_pt_base = (pde_t)page2pa(pp);
        // #填上就不为空了
        pgdir[PDX(va)] = new_pt_base|PTE_W|PTE_P;
        // #返回PTE
        pt_base = (pte_t)(new_pt_base);
        return &(pt_base[PTX(va)]);
    
    }

}

上面编译时出现一处错误:subscripted value is neither array nor pointer nor vector

也就是想对一个变量名使用下标,它必须是数组或者指针。

 

然后我们琢磨一下这个函数:

// Map [va, va+size) of virtual address space to physical [pa, pa+size)
// in the page table rooted at pgdir.  Size is a multiple of PGSIZE.
// Use permission bits perm|PTE_P for the entries.
//
// This function is only intended to set up the ``static'' mappings
// above UTOP. As such, it should *not* change the pp_ref field on the
// mapped pages.
//
// Hint: the TA solution uses pgdir_walk
static void
boot_map_region(pde_t *pgdir, uintptr_t va, size_t size, physaddr_t pa, int perm)

实现的是虚拟地址[va,va+size]到物理地址[pa,pa+size]的映射

注意的问题是:

不论物理地址还是虚拟地址要PGSIZE对齐

那么应该映射多少页?

左往左延伸,右往右延伸,PGSIZE大小对齐,然后除以PGSIZE。

 

posted @ 2014-07-27 12:13  乾卦  阅读(178)  评论(0)    收藏  举报