2021 MIT6.S081 Lab: page table

Lab: page table

2021的Lab3在设计上相比2020精简了许多内容,很快就做完了,第三个assignment的边界检查没做也能过就懒得做了

Speed up system calls

  1. 增加结构体struct proc字段:

    struct usyscall* usyscall;
    
  2. 在函数allocproc中增加字段:

    static struct proc*
    allocproc(void)
    {
        struct proc *p;
    
        for(p = proc; p < &proc[NPROC]; p++) {
            acquire(&p->lock);
            if(p->state == UNUSED) {
                goto found;
            } else {
                release(&p->lock);
            }
        }
        return 0;
    
        found:
        p->pid = allocpid();
        p->state = USED;
    
        // Allocate a trapframe page.
        if((p->trapframe = (struct trapframe *)kalloc()) == 0){
            freeproc(p);
            release(&p->lock);
            return 0;
        }
    
        if((p->usyscall = (struct usyscall*)kalloc()) == 0) {
            freeproc(p);
            release(&p->lock);
            return 0;
        }
    
        // An empty user page table.
        p->pagetable = proc_pagetable(p);
        if(p->pagetable == 0){
            freeproc(p);
            release(&p->lock);
            return 0;
        }
    
        copyout(p->pagetable, USYSCALL, (char*)&(p->pid), sizeof(p->pid));
    
        // Set up new context to start executing at forkret,
        // which returns to user space.
        memset(&p->context, 0, sizeof(p->context));
        p->context.ra = (uint64)forkret;
        p->context.sp = p->kstack + PGSIZE;
    
        return p;
    }
    
  3. freeproc中增加字段:

    if(p->usyscall)
        kfree((void*)p->usyscall);
    p->usyscall = 0;
    
  4. 在函数proc_pagetable中增加字段:

    if(mappages(pagetable, USYSCALL, PGSIZE, (uint64)(p->usyscall), PTE_U|PTE_R) < 0) {
        uvmunmap(pagetable, USYSCALL, 1, 0);
        uvmfree(pagetable, 0);
        return 0;
    }
    
  5. 在函数proc_freepagetable中增加字段:

    uvmunmap(pagetable, USYSCALL, 1, 0);
    

Print a page table

  1. vm.c中定义函数_vmprintvmprint

    void _vmprint(pagetable_t pgtbl, int level) {
        for(int i = 0; i<512; ++i)
            if(pgtbl[i] & PTE_V)
                switch(level) {
                    case 0:
                        printf("..%d: pte %p pa %p\n", i, pgtbl[i], PTE2PA(pgtbl[i]));
                        _vmprint((pagetable_t)PTE2PA(pgtbl[i]), level+1);
                        break;
                    case 1:
                        printf(".. ..%d: pte %p pa %p\n", i, pgtbl[i], PTE2PA(pgtbl[i]));
                        _vmprint((pagetable_t)PTE2PA(pgtbl[i]), level+1);
                        break;
                    case 2:
                        printf(".. .. ..%d: pte %p pa %p\n", i, pgtbl[i], PTE2PA(pgtbl[i]));
                        _vmprint((pagetable_t)PTE2PA(pgtbl[i]), level+1);
                        break;
            }
    
        return;
    }
    
    void vmprint(pagetable_t pgtbl) {
        printf("page table %p\n", pgtbl);
        _vmprint(pgtbl, 0);
        return;
    }
    
  2. def.h中增加函数声明:

    void            vmprint(pagetable_t);
    
  3. 在函数exec中增加字段:

    if(p->pid == 1)
        vmprint(p->pagetable);
    

Detecting which pages have been accessed

  1. def.h中增加函数声明:

    pte_t* walk(pagetable_t, uint64, int);
    
  2. riscv.h中增加宏定义:

    #define PTE_A (1L << 6)
    
  3. 修改函数sys_pgaccess内容:

    int
    sys_pgaccess(void)
    {
        uint64 uva, dst;
        int len;
        uint buffer = 0;
        pte_t* pte;
        struct proc* p = myproc();
    
        if(argaddr(0, &uva) | argint(1, &len) | argaddr(2, &dst))
            return -1;
    
        uva = PGROUNDDOWN(uva);
    
        for(int i = 0; i<len; ++i, uva+=PGSIZE) {
            pte = walk(p->pagetable, uva, 0);
            if(*pte & PTE_A) {
                buffer |= (1L << i);
                *pte &= ~PTE_A;
            }
        }
    
        copyout(p->pagetable, dst, (char*)&buffer, sizeof(buffer));
    
        return 0;
    }
    

结果

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值