这里给出Lab2 System calls的解析。

学习资料:

参考资料:

准备工作

修改测评脚本:

#!/usr/bin/env python

修改为:

#!/usr/bin python

测试命令由

./grade-lab-syscall trace

修改为:

sudo python3 grade-lab-syscall trace

System call tracing (moderate)

调用过程:

  • trace.c设置调用trace
  • trace调用sys_trace
    • 设置mask
  • fork产生子进程
  • syscall调用子进程

流程:

  • 在/xv6-labs-2020/kernel/proc.h的结构proc中添加mask字段记录需要trace的进程;

  • 在/xv6-labs-2020/kernel/sysproc.c中添加如下函数,该函数的作用是解析参数,设置mask:

    // add
    uint64 sys_trace(void){
      uint64 p;
      // 获得参数
      if(argaddr(0, &p) < 0)
        return -1;
      myproc()->mask = p;
    
      return 0;
    }
  • 修改/xv6-labs-2020/kernel/syscall.c的函数syscall:

    void
    syscall(void)
    {
      int num;
      struct proc *p = myproc();
    
      num = p->trapframe->a7;
      if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
        p->trapframe->a0 = syscalls[num]();
    
        // add
        if ((1 << num) & p->mask){
          printf("%d: syscall %s -> %d\n",
                  p->pid, sysnames(num), p->trapframe->a0);
        }
      } else {
        printf("%d %s: unknown sys call %d\n",
                p->pid, p->name, num);
        p->trapframe->a0 = -1;
      }
    }

测试:

sudo python3 grade-lab-syscall trace
make: 'kernel/kernel' is up to date.
== Test trace 32 grep == trace 32 grep: OK (1.2s) 
== Test trace all grep == trace all grep: OK (0.9s) 
== Test trace nothing == trace nothing: OK (1.1s) 
== Test trace children == trace children: OK (10.3s) 

Sysinfo (moderate)

调用过程:

  • sysinfotest.c设置调用sysinfo
  • sysinfo调用sys_sysinfo
  • sys_sysinfo计算freemem以及nproc

流程:

  • 在/xv6-labs-2020/kernel/kalloc.c中添加函数:

    // add
    uint64 freemem(void)
    {
      struct run *r;
    
      r = kmem.freelist;
      uint64 cnt = 0;
      while (r){
        cnt += 4096;
        r = r->next;
      }
    
      return cnt;
    }
  • 在/xv6-labs-2020/kernel/proc.c中添加函数:

    // add
    uint64 nproc(void)
    {
      struct proc *p;
      uint64 cnt = 0;
    
      for(p = proc; p < &proc[NPROC]; p++) {
        if(p->state != UNUSED) {
          cnt++;
        }
      }
    
      return cnt;
    }
  • 在/xv6-labs-2020/kernel/sysproc.c中添加函数:

    // add
    uint64 sys_sysinfo(void){
      // 参数地址
      uint64 addr;
      if(argaddr(0, &addr) < 0)
        return -1;
      // 保存信息
      struct sysinfo sys_info;
      sys_info.freemem = freemem();
      sys_info.nproc = nproc();
      
      if (copyout(myproc()->pagetable, addr, (char *)&sys_info, sizeof(sys_info)) < 0){
        return -1;
      }
      return 0;
    }

说明:

  • copyout函数将pagetable中sys_info位置开始的sizeof(sys_info)字节复制到addr地址,即将kernel中数据复制给user。