MIT6.s081-2020 Lab2 System Calls

MIT6.s081-2020 Lab2 System Calls

lab 2文档

准备

git checkout syscall
make clean

System call trace

引言

在本任务中,您将添加一个系统调用跟踪功能,该功能可能会在以后调试实验时帮助您。您将创建一个新的trace将控制跟踪的系统调用。它应该采用一个参数,一个整数“掩码”,其位指定要跟踪的系统调用。例如,要跟踪 fork 系统调用,程序调用trace(1 << SYS_fork), 在哪里SYS_fork是来自的系统调用号kernel/syscall.h. 如果掩码中设置了系统调用的编号,则必须修改 xv6 内核以在每个系统调用即将返回时打印出一行。该行应包含进程id、系统调用的名称和返回值;您不需要打印系统调用参数。这trace系统调用应该启用对调用它的进程以及它随后派生的任何子进程的跟踪,但不应影响其他进程。

实现

这一部分是要求我们实现一个系统调用的跟踪,按照HINT一步步做下去即可。
HINT1:在Makefile的UPROGS中添加$U/_trace
打开目录可以发现已经提供了一个user/trace.c文件,先在Makefile里添加一下即可。
user/trace.c

if (trace(atoi(argv[1])) < 0) {
   
    fprintf(2, "%s: trace failed\n", argv[0]);
    exit(1);
}

可以看到trace.c里面调用了trace()方法(来自user.h),trace接收一个int参数,返回int,并且如果执行失败返回负值。
然后这个trace()函数的作用是,输入参数是掩码,因为int是32位最多能表示31个系统调用,被置为1的那个系统调用位就会被跟踪并打印信息。
HINT2:在user/user.h中添加系统调用的原型,在user/usys.pl中添加一个占位,并在kernel/syscall.h中添加一个系统调用号。
Makefile调用perl脚本user/usys.pl来生成user/usys.Susys.S也就是实际的系统调用代码(stub),它使用RISC-V的ecall指令来进入内核态。修复了编译问题后运行trace 32 grep hello README依然执行失败因为你还没有在内核中实现这个系统调用。
usys.pl的内容

sub entry {
   
    my $name = shift;
    print ".global $name\n";
    print "${name}:\n";
    print " li a7, SYS_${name}\n";
    print " ecall\n";
    print " ret\n";
}

ecall: xv6是基于RISC-V指令集的,在RISV-V指令集中ecall代表系统调用。

li: 是一个加载立即数到寄存器的指令,格式是li rd, immediate,表示x[rd] = immediate,将常量加载到 x[rd]中。

SYS_${name}的含义是在kernel/syscall.h中#define SYS_${name} xxx的系统调用号,这样就可以告诉ecall要调用几号系统调用。
user/user.h中添加函数原型。

int trace(int);

user/usys.pl中添加trace的占位。

entry("trace");

syscall.h里添加系统调用号。

#define SYS_close  21
#define SYS_trace  22 // NEW

HINT3:在kernel/syspro.c中添加sys_trace()函数,sys_trace()通过在proc struct的新变量中存储参数来实现这个新的系统调用。从用户空间检索系统调用参数的函数位于kernel/syscall.c中,可以在kernel/sysproc.c中看到这些函数的使用示例。
查看kernel/syscall.c中函数可以发现:
syscall.c中的argint()函数的实现如下,trapframe是的用户进程陷入(trap)内核之前的寄存器等上下文信息。

// Fetch the nth 32-bit system call argument.
int argint(int n, int *ip) {
   
  *ip = argraw(n);
  return 0;
}

static uint64 argraw(int n) {
   
  struct proc *p = myproc();
  switch (n) {
   
  case 0:
    return p->trapframe->a0;
  case 1:
    return p->trapframe->a1;
  case 2:
    return p->trapframe->a2;
  case 3:
    return p->trapframe->a3;
  case 4:
    return p->trapframe
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值