6.828:Lab2 Memory Management 实验总结

Part1 Physical Page Management

Exercise1

boot_alloc()

result = nextfree;
if (n > 0) {
     nextfree = ROUNDUP((char *) (nextfree + n), PGSIZE);
}
return result;

mem_init()

pages = (struct PageInfo*) boot_alloc(sizeof(struct PageInfo) * npages);
memset(pages, 0, sizeof(struct PageInfo) * npages)

page_init()

#define MARK_FREE(_i)                         \
({                                            \
    pages[_i].pp_ref = 0;                     \
    pages[_i].pp_link = page_free_list;       \
    page_free_list = &pages[_i];              \
})

#define MARK_USE(_i)                          \
({                                            \
    pages[_i].pp_ref = 0;                     \
    pages[_i].pp_link = NULL;                 \
})

    page_free_list = NULL;
    physaddr_t kern_pgdir_end = PADDR(boot_alloc(0));
    size_t i;

    // 1)
    MARK_USE(0);

    // 2)
    for (i = 1; i < npages_basemem; i++) {
        MARK_FREE(i);
    }

    // 3)
    for (i = IOPHYSMEM / PGSIZE; i < EXTPHYSMEM / PGSIZE; i++) {
        MARK_USE(i);
    }

    // 4)
    for (i = EXTPHYSMEM / PGSIZE; i < kern_pgdir_end / PGSIZE; i++) {
        MARK_USE(i);
    }
    for (i = kern_pgdir_end / PGSIZE; i < npages; i++) {
        MARK_FREE(i);
    }

#undef MARK_FREE
#undef MARK_USE

page_alloc()

if (!page_free_list) {
    return NULL;
}
struct PageInfo* alloc_page = page_free_list;
page_free_list = page_free_list->pp_link;
alloc_page->pp_link = NULL;
alloc_page->pp_ref = 0;
if (alloc_flags & ALLOC_ZERO) {
    memset(page2kva(alloc_page), 0, PGSIZE);
}
return alloc_page;

page_free()

if (pp->pp_ref != 0 || pp->pp_link != NULL) {
    panic("page_free");
}

pp->pp_link = page_free_list;
page_free_list = pp;

Part2 Virtual Memory

Exercise 2. Look at chapters 5 and 6 of the Intel 80386 Reference Manual, if you haven’t done so already. Read the sections about page translation and page-based protection closely (5.2 and 6.4). We recommend that you also skim the sections about segmentation; while JOS uses the paging hardware for virtual memory and protection, segment translation and segment-based protection cannot be disabled on the x86, so you will need a basic understanding of it.

Virtual, Linear, and Physical Addresses

Exercise3

C TypeAddress Type
T*Virtual
uintptr_tVirtual
physaddr_tPhysical

Question1

uintptr_t

Reference counting

Page Table Management

Exercise4

pgdir_walk()

pde_t *pde;
pte_t *pgtab;

pde = &pgdir[PDX(va)];
if (*pde & PTE_P) {
    pgtab = (pte_t*)KADDR(PTE_ADDR(*pde));
} else {
    struct PageInfo *pp = page_alloc(ALLOC_ZERO);
    if (!create || !page)
        return NULL;
    pp->pp_ref += 1;
    pgtab = (pte_t*)KADDR(page2pa(pp));
    memset(pgtab, 0, PGSIZE);
    *pde = PADDR(pgtab) | PTE_P | PTE_W | PTE_U;
}
return &pgtab[PTX(va)];

boot_map_region

char *a, *last;
pte_t* pte;
a = (char*)va;
last = (char*)(va + size - 1);
while(1) {
    if((pte = pgdir_walk(pgdir, a, 1)) == NULL)
        return -1;
    if(*pte & PTE_P)
        panic("remap");
    *pte = pa | perm | PTE_P;
    if (a == last)
        break;
    a += PGSIZE;
    pa += PGSIZE;
}

page_lookup()

pte_t *pte = pgdir_walk(pgdir, va, 0);

if (!pte || !(*pte & PTE_P)) {
    return NULL;
}

if (pte_store) {
    *pte_store = pte;
}

return pa2page(PTE_ADDR(*pte));

page_remove()

struct PageInfo *pp;
pte_t *pte;
if (pp = page_lookup(pgdir, va, &pte)) {
    page_decref(pp);
    memset(pte, 0, sizeof(pte_t));
    tlb_invalidate(pgdir, va);
}

page_insert()

pte_t *pte;

if (!(pte = pgdir_walk(pgdir, va, 1))) {
    return -E_NO_MEM;
}
pp->pp_ref++;
page_remove(pgdir, va)
*pte = page2pa(pp) | perm | PTE_P;
return 0;

Part3 Kernel Address Space

内核和用户环境空间以ULIM为分割线,ULIM以上为内核空间,以下为用户环境空间

Permissions and Fault Isolation

用户环境无法访问ULIM以上的空间,内核和用户环境都可以读取[UTOP,ULIM)之间的空间,UTOP以下的空间为用户环境空间,可以设置相应的权限

Initializing the Kernel Address Space

Exercise5

mem_init()

boot_map_region(kern_pgdir, UPAGES, PTSIZE, PADDR(pages), PTE_U);
boot_map_region(kern_pgdir, KSTACKTOP - KSTKSIZE, KSTKSIZE, PADDR(bootstacktop), PTE_W);
boot_map_region(kern_pgdir, KERNBASE, ~(uint32_t)0 - KERNBASE + 1, 0, PTE_W);

Question2:

3BD号页目录项,指向的是kern_pgdir

3BC号页目录项,指向的是pages数组

3BF号页目录项,指向的是bootstack

3C0~3FF号页目录项,指向的是kernel

Question3:

因为用户空间和内核空间的页表项中的PTE_U位不同。本质上是x86处理器的MMU通过CS寄存器的特权级结合页表项的PTE_U位来判断当前代码是否有访问特定地址的权限

Question4:

由于这个操作系统利用一个大小为4MB的空间UPAGES来存放所有的页的PageInfo结构体信息,每个结构体的大小为8B,所以一共可以存放512K个PageInfo结构体,所以一共可以出现512K个物理页,每个物理页大小为4KB,自然总的物理内存占2GB。

Question5:

管理内存的开销为1个一级页表与1024个二级页表,再加上4MB的PAGES,即 1025 * 4KB + 4MB = 6100KB

Question6:

在执行指令jmp *%eax时,会重新设置EIP的值,使其大于KERNBASE。EIP处于低地址仍然可以运行,是因为entry_pgdir包含了虚拟内存0~4MB到物理内存0~4MB的映射,目的是兼容从物理访存到虚拟访存

Address Space Layout Alternatives

进程的虚拟地址空间布局不唯一

Reference

操作系统实验报告_MIT 6.828 JOS Lab2 实验报告
MIT-6.828 Lab 2: Memory Management实验报告

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值