【MIT6.S081】Lab5: xv6 lazy page allocation(详细解答版)

实验内容网址:https://xv6.dgs.zone/labs/requirements/lab5.html

本实验的代码分支:https://gitee.com/dragonlalala/xv6-labs-2020/tree/lazy3/

Eliminate allocation from sbrk()

关键点:p->sz的含义

思路:

sbrk(n)系统调用将进程的内存大小增加n个字节,然后返回新分配区域的开始部分(即旧的大小)。新的sbrk(n)应该只将进程的大小(myproc()->sz)增加n,然后返回旧的大小。因此直接修改sys_sbrk()函数,注释掉对growproc()函数的调用,直接修改p->sz。

uint64
sys_sbrk(void)
{
   
   
  int addr;
  int n;

  if(argint(0, &n) < 0)
    return -1;
  addr = myproc()->sz;
  // lab5-1
  myproc()->sz += n;    // increase size but not allocate memory
//  if(growproc(n) < 0)
//    return -1;
  return addr;
}

进行 echo hi 测试,实验结果如图所示

Lazy allocation

这题才是本实验的主要部分,上面的实验在调用sbrk增加或者减少内存时并没有对物理内存进行操作,这会引起页面错误,本题就是为了解决内存增加时出现的页面错误。

思路&步骤

对于这部分的思路和步骤可以跟着提示进行展开。

  1. kernel/trap.c文件的usertrap()函数中对r_scause()为13或者15的情况进行处理,这两种情况是出现了页面错误。通过r_stval()函数获得出现页面错误的虚拟地址。参考growproc()函数中对kalloc()mappages()的调用,为出现报错的虚拟地址申请1页物理地址(内存),是的,1页。物理内存申请成功后将虚拟地址映射到物理地址上。这段代码中有一点要注意的是如果出现物理内存申请不成功 或者映射失败 的情况,需要将p->killed置为1,标记当前进程后就需要立即去exit(-1)了,所以下面的代码我添加了goto来实现这个效果。如果没加goto,则会导致物理内存申请不成功后反而去初始化物理内存,导致其他错误。
...
else if((which_dev = devintr()) != 0){
   
   
    // ok
  } else if(r_scause() == 13 || r_scause() == 15){
   
   
    
    // 出现报错的虚拟地址
      uint64 va = r_stval();
       // 虚拟地址高于sbrk分配的虚拟地址则杀死进程
      // 申请1页物理内存
      char* pa = kalloc();
      if(pa == 0){
   
    // 申请不成功
        printf("alloc physical memory failed");
        p->killed = 1;
        goto end;
      }
      // 初始化物理内存
      memset(pa, 0, PGSIZE);
      // 映射, 将出错的虚拟地址向下舍入到页面边界,因为va所在的这一页还没有对应的物理内存
      if(mappages(p->pagetable, PGROUNDDOWN(va), PGSIZE, (uint64)pa, PTE_W|PTE_X|PTE_R|PTE_U)){
   
   
        // 映射失败,释放物理内存
        kfree(pa);
        p->killed = 1;
        goto end;
      }
    
    

  }else {
   
   
    printf("usertrap(): unexpected scause %p pid=%d\n", r_scause(), p->pid);
    printf("            sepc=%p stval=%p\n", r_sepc(), r_stval());
    p->killed = 1;
  }
  
  end:
  if(p->killed){
   
   
    exit(-
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值