tsinghua-ucore-lab2

tsinghua-ucore-lab2

练习1

实现 first-fit 连续物理内存分配算法

static struct Page *
default_alloc_pages(size_t n) {
    assert(n > 0);
    if (n > nr_free) {
        return NULL;
    }
    struct Page *page = NULL;
    list_entry_t *le = &free_list;
    while ((le = list_next(le)) != &free_list) {
        struct Page *p = le2page(le, page_link);
        if (p->property >= n) {
            page = p;
            break;
        }
    }
    if (page != NULL) {
        if (page->property > n) {
            struct Page *p = page + n;
            p->property = page->property - n;
            list_add(&(page->page_link), &(p->page_link));
        }
        int i=0;
        for (; i<n; i++) {
            ClearPageProperty(page + i);
        }
        page->property = 0;
        list_del(&(page->page_link));
        nr_free -= n;
    }
    return page;
}

static void
default_free_pages(struct Page *base, size_t n) {
    assert(n > 0);
    struct Page *p = base;
    for (; p != base + n; p ++) {
        assert(!PageReserved(p) && !PageProperty(p));
        p->flags = 0;   // Clear the status of page frame
        set_page_ref(p, 0); // Set the reference count of page frame to 0
    }
    base->property = n; // Set the count of free page frames
    SetPageProperty(base); // Indicate that the page is head page of a free memmory block
    list_entry_t *le = list_next(&free_list);
    // Try to merge blocks at lower or higher addresses
    while (le != &free_list) {
        p = le2page(le, page_link);
        le = list_next(le);
        if (base + base->property == p) { // Merge block at higher address
            base->property += p->property;
            ClearPageProperty(p);   // Higher block is not the head of free block yet, so we should remove it's head flag and remove it from the list of free pages
            list_del(&(p->page_link));
        }
        else if (p + p->property == base) { // Merge block at lower address
            p->property += base->property;
            ClearPageProperty(base);
            base = p;   // Change the current block's address
            list_del(&(p->page_link));
        }
    }
    nr_free += n;   // Increase the total count of free pages
    // Add the block at correct position
    le = list_next(&free_list);
    while (le != &free_list) {
        p = le2page(le, page_link);
        if (base + base->property < p) { // Find the correct position
            break;
        }
        le = list_next(le);
    }
    list_add_before(le, &(base->page_link));
}

练习2

实现寻找虚拟地址对应的页表项

pte_t *
get_pte(pde_t *pgdir, uintptr_t la, bool create) {
    // Get page directory index.
    unsigned int pdx = PDX(la);
    // Find the address of page entry in page directory.
    pde_t *ppde = &pgdir[pdx];
    // Check if page is present or not.
    if (!(*ppde & PTE_P))
    {
        struct Page *ppage;
        if (!create || (ppage = alloc_page()) == NULL )
        {
            return NULL;
        }
        set_page_ref(ppage, 1);
        uintptr_t pa = page2pa(ppage);
        memset(page2kva(ppage), 0, PGSIZE);
        *ppde = pa | PTE_P | PTE_U | PTE_W;
    }
    return &((pte_t *)KADDR(PDE_ADDR(*ppde)))[PTX(la)];
}

练习3

释放某虚地址所在的页并取消对应二级页表项的映射

static inline void
page_remove_pte(pde_t *pgdir, uintptr_t la, pte_t *ptep) {
    // check if the page table entry is not present
    if (!(*ptep & PTE_P))
    {
        return;
    }
    // find corresponding page to pte
    struct Page *page = pte2page(*ptep);
    // decrease page reference
    page_ref_dec(page);
    // if the reference of page is 0, then this page shoule be free
    if (page->ref == 0)
    {
        free_page(page);
    }
    // clear 2nd level page table entry
    *ptep = 0;
    // flush TLB
    tlb_invalidate(pgdir, la);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值