mit6.s081 lab5.1&5.2

MIT 6.s081 lab5.1&5.2

No.1 写在前面的话

前两节还是挺简单的,frans教授视频中也有演示,不过因为本人技术力不好写的很简单,哈哈。话不多说,开搞!

No.2 实验开始

5.1

根据提示,删除页面分配代码,看代码可知,通过追溯唯一的**growproc()**函数,或者根据函数名可知,这就是页面分配的代码,将其注释:

/*
  if(growproc(n) < 0)
    return -1;
*/

接下来将进程的内存大小增加n个字节,已知addr赋值为当前进程大小,可是提示必须返回旧的部分,那么不应该修改addr,而是在当前进程的基础上修改:

  myproc()->sz += n;

这样就完成了。

5.2

实验是循序渐进的,5.1我们初步得到页面错误,5.2开始尝试解决问题。通过阅读YOUR JOB可知,主要任务有三个:分配一个物理页面,映射到发生错误的地址,返回用户空间。

根据提示,模仿trap中系统调用的语句,补充 else if(r_scause() == 13 || r_scause() == 15){},其余代码均在里面完成。

stval保存了页面错误的虚拟地址,因此可以通过分配变量读取:

    uint64 va = r_stval();

继续参看提示,看一看uvmalloc()函数:

uint64
uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz)
{
  char *mem;
  uint64 a;

  if(newsz < oldsz)
    return oldsz;

  oldsz = PGROUNDUP(oldsz);
  for(a = oldsz; a < newsz; a += PGSIZE){
    mem = kalloc();
    if(mem == 0){
      uvmdealloc(pagetable, a, oldsz);
      return 0;
    }
    memset(mem, 0, PGSIZE);
    if(mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_W|PTE_X|PTE_R|PTE_U) != 0){
      kfree(mem);
      uvmdealloc(pagetable, a, oldsz);
      return 0;
    }
  }
  return newsz;
}

我们可知它主要负责的是向上增长内存,提示进一步告诉我们需要利用kalloc和mappages,那么就将与之相关的代码沿用过来:

  else if(r_scause() == 13 || r_scause() == 15){
    uint64 va = r_stval();
  	char *mem;
      
    mem = kalloc();
    memset(mem, 0, PGSIZE);
    if(mappages(p->pagetable, va, PGSIZE, (uint64)mem, PTE_W|PTE_X|PTE_R|PTE_U) != 0){
      kfree(mem);
      p->killed = 1;
    }
  }

当然,我们还需要将地址向下舍入到页边界,但我不知道这样做的理由是什么【按理来说已经是出错的地址,为什么还要舍入呢?】:

uint64 va = PGROUNDDOWN((uint64)r_stval());
//r_stval()!!!丢了()!难怪一直remap!

现在qemu会出现panic,只需将相对应的panic注释加continue就好。当然,我这些代码可以运行但确实很粗糙,也有些细究的错误;为了解决上面的疑问,在这里贴上frans的代码和他的解释:

Imgur

“如果有物理内存,首先会将内存内容设置为0,之后将物理内存page指向用户地址空间中合适的虚拟内存地址。具体来说,我们首先将虚拟地址向下取整,这里引起page fault的虚拟地址是0x4008,向下取整之后是0x4000。之后我们将物理内存地址跟取整之后的虚拟内存地址的关系加到page table中。”

【用时半天】

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值