MIT 6.828 Homework: Xv6 System Calls

  • MIT 6.828 Homework: Xv6 System Calls已关闭评论
  • 121 次浏览
  • A+
所属分类:linux技术
摘要

根据提示,应该在syscall.c中修改syscall()。
首先在syscall.c中增加对应系统调用名称的数组:


Part One: System call tracing

任务:修改Xv6内核的代码来打印出每个系统调用以及返回值

根据提示,应该在syscall.c中修改syscall()。
首先在syscall.c中增加对应系统调用名称的数组:

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", }; 

接着在syscall()中添加打印命令:

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]();     cprintf("%s -> %dn", syscalls_name[num], curproc->tf->eax);   } else {     cprintf("%d %s: unknown sys call %dn", curproc->pid, curproc->name, num);     curproc->tf->eax = -1;   } } 

最终执行结果如下:

xv6... cpu0: starting 0 sb: size 1000 nblocks 941 ninodes 200 nlog 30 logstart 2 inodestart 32 bmap start 58 exec -> 0 open -> 0 dup -> 1 dup -> 2 iwrite -> 1 nwrite -> 1 iwrite -> 1 twrite -> 1 :write -> 1  write -> 1 swrite -> 1 twrite -> 1 awrite -> 1 rwrite -> 1 twrite -> 1 iwrite -> 1 nwrite -> 1 gwrite -> 1  write -> 1 swrite -> 1 hwrite -> 1  write -> 1 fork -> 2 exec -> 0 open -> 3 close -> 0 $write -> 1  write -> 1  

注:shell的输出和系统调用的调用路径混在了一起,原因是shell是通过系统调用write来打印输出的

Part Two: Date System Call

任务: 在Xv6中新增一个系统调用date。使用定义于lapic.c中的函数cmostime(),以系统调用uptime为例,观察如何添加一个系统调用。并且在用户层添加一个调用系统调用date的程序。

  1. 首先使用grep - n uptime *.[chS]命令在源码中查找uptime相关的代码,接下来逐个查看搜索到的位置,模仿写出date系统调用所需要的代码
❯ grep -n uptime *.[chS] syscall.c:105:extern int sys_uptime(void); syscall.c:121:[SYS_uptime]  sys_uptime, syscall.h:15:#define SYS_uptime 14 sysproc.c:83:sys_uptime(void) user.h:25:int uptime(void); usys.S:31:SYSCALL(uptime) 
  1. 在syscall.c的对应位置添加代码后如下:
extern int sys_chdir(void); extern int sys_close(void); extern int sys_dup(void); extern int sys_exec(void); extern int sys_exit(void); extern int sys_fork(void); extern int sys_fstat(void); extern int sys_getpid(void); extern int sys_kill(void); extern int sys_link(void); extern int sys_mkdir(void); extern int sys_mknod(void); extern int sys_open(void); extern int sys_pipe(void); extern int sys_read(void); extern int sys_sbrk(void); extern int sys_sleep(void); extern int sys_unlink(void); extern int sys_wait(void); extern int sys_write(void); extern int sys_uptime(void); extern int sys_date(void); // 新添加  static int (*syscalls[])(void) = { [SYS_fork]    sys_fork, [SYS_exit]    sys_exit, [SYS_wait]    sys_wait, [SYS_pipe]    sys_pipe, [SYS_read]    sys_read, [SYS_kill]    sys_kill, [SYS_exec]    sys_exec, [SYS_fstat]   sys_fstat, [SYS_chdir]   sys_chdir, [SYS_dup]     sys_dup, [SYS_getpid]  sys_getpid, [SYS_sbrk]    sys_sbrk, [SYS_sleep]   sys_sleep, [SYS_uptime]  sys_uptime, [SYS_open]    sys_open, [SYS_write]   sys_write, [SYS_mknod]   sys_mknod, [SYS_unlink]  sys_unlink, [SYS_link]    sys_link, [SYS_mkdir]   sys_mkdir, [SYS_close]   sys_close, [SYS_date]    sys_date, // 新添加 }; 
  1. 在syscall.h中添加代码:
#define SYS_date   22 
  1. 在user.h中添加代码:
int date(struct rtcdate*); 
  1. 在usys.S中添加代码:
SYSCALL(date) 
  1. 在sysproc.c中添加代码:
int sys_date(void) {     struct rtcdate* r = 0;     if (argptr(0, (char**)&r, sizeof(*r) < 0)) {         return -1;     }     cmostime(r);     return 0; } 
  1. 以上在操作系统中添加了一个系统调用,下面编写一个执行该系统调用的命令,编写date.c,代码如下:
#include "types.h" #include "user.h" #include "date.h"  int main(int argc, char *argv[]) {   struct rtcdate r;    if (date(&r)) {     printf(2, "date failedn");     exit();   }    printf(1, "%d-%d-%d %d:%d:%dn", r.year, r.month, r.day, r.hour, r.minute, r.second);    exit(); } 
  1. 在Makefile中的UPROG中添加
_date 

在完成以上步骤后,成功添加了系统调用date以及调用它的命令date,测试结果如下:

xv6... cpu0: starting 0 sb: size 1000 nblocks 941 ninodes 200 nlog 30 logstart 2 inodestart 32 bmap start 58 init: starting sh $ date 2022-11-10 18:19:21 $