MIT 6.828 Homework: Xv6 System Calls

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 -> %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;
  }
}

最终执行结果如下:

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 failed\n");
    exit();
  }

  printf(1, "%d-%d-%d %d:%d:%d\n", 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
$

热门相关:斗神战帝   第一神算:纨绔大小姐   大神你人设崩了   天启预报   豪门闪婚:帝少的神秘冷妻