MIT6.828 Homework3 xv6 system calls

Part One: System call tracing

实验内容

任务是修改xv6内核,使得每一次系统调用打印出一行代码,格式为:

系统调用名称->系统调用返回值

样例:

fork -> 2
exec -> 0
open -> 3
close -> 0
$write -> 1
 write -> 1

实验过程

在github上下载xv6-public的代码并进入该目录下。vim syscall.c

根据注释可知系统调用number在%eax里,也就是说syscalls[]()函数返回的是系统调用number,并且把它存储在值 curproc->tf->eax内。所以只需要把系统调用名称输出即可。代码如下:

/*定义系统调用名称*/
static char *syscalls_name[] = {
[SYS_fork]    "fork",
[SYS_exit]    "exit",
[SYS_wait]    "wait",
[SYS_pipe]    "pipe",
[SYS_read]    "read",
[SYS_kill]    "kill",
[SYS_exec]    "exec",
[SYS_fstat]   "fstat",
[SYS_chdir]   "chdir",
[SYS_dup]     "dup",
[SYS_getpid]  "getpid",
[SYS_sbrk]    "sbrk",
[SYS_sleep]   "sleep",
[SYS_uptime]  "uptime",
[SYS_open]    "open",
[SYS_write]   "write",
[SYS_mknod]   "mknod",
[SYS_unlink]  "unlink",
[SYS_link]    "link",
[SYS_mkdir]   "mkdir",
[SYS_close]   "close",
};

void
syscall(void)
{
  int num;
  struct proc *curproc = myproc();

  num = curproc->tf->eax;
  if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
    curproc->tf->eax = syscalls[num]();
    /*按照格式输出名称和number*/
    cprintf("%s -> %d\n",syscalls_name[num],curproc->tf->eax);
  } else {
    cprintf("%d %s: unknown sys call %d\n",
            curproc->pid, curproc->name, num);
    curproc->tf->eax = -1;
  }
}

 实验结果

make qemu后出现结果

Part Two: Date system call

实验内容

添加一个date系统调用,按照自己规定的格式返回时间。

实验过程

使用grep -n uptime *.[chS] 追踪uptime系统调用。

date系统调用仿写uptime,在追踪到的头文件和c文件中补充代码。

值得注意的是,在user.h中是函数的定义,按照官方给出的需要补充在date.c的代码,我们在user.h中添加函数定义:

int date(struct rtcdate*); 其他均按照uptime的格式即可。

在sysproc.c中sys_date(void)代码:

int sys_date(void){
        struct rtcdate *r;
   if(argptr(0,(void *)&r, sizeof(*r)) < 0)
           return -1;
   cmostime(r);
   return 0;
}

date.c的代码:

#include "types.h"
#include "user.h"
#include "date.h"

int
main(int argc, char *argv[])
{
  struct rtcdate r;
 // printf("running date");
  if (date(&r)) {
    printf(2, "date failed\n");
    exit();
  }

  // your code to print the time in any format you like...
   printf(1, "%d-%d %d %d:%d:%d\n", r.month, r.day, r.year, r.hour, r.minute, r.second);
  exit();
}

实验结果

make qemu后在qemu仿真器里输入命令,出现结果

小结

 对于date命令的执行,推测过程应该是这样:命令行输入date,找到date.c文件开始执行,执行到date(&r)语句时,因为在usys.S文件中声明了SYSCALL(date),所以发现这是个系统调用,于是开始陷入。发现sys_date系统调用执行函数,将参数r赋值,系统调用执行结束,返回用户进程,恢复到date.c/main函数执行现场,继续执行输出时间。

ATTENCION

在进行任务二的时候,需要把任务一中更改的代码注释,恢复到原状。不然在qemu中无法进行命令的输入。可能是因为shell的输出和系统调用跟踪是混合的,因为shell使用write syscall来打印它的输出。 (这是官网给出的提示,难道就是提示这个的?)

另外两个challenge都没有做,先放一放...涉及到寄存器就搞不懂惹...

猜你喜欢

转载自blog.csdn.net/qq_43012789/article/details/107746030