操作系统原理作业(四):xv6 system calls

System call tracing

实验要求

第一部分的主要任务是在进行系统调用时,打印出系统调用的名字和返回值。

实验思路

系统调用函数syscall()在syscall.c文件中,我们只需要修改syscall()函数即可,即在syscall()函数内添加对应的printf语句。

实验代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
void
syscall(void)
{
int num;
num = proc->tf->eax;
if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
proc->tf->eax = syscalls[num]();
switch (num) {
case SYS_fork:
cprintf("fork -> ");
break;
case SYS_exit:
cprintf("exit -> ");
break;
case SYS_wait:
cprintf("wait -> ");
break;
case SYS_pipe:
cprintf("pipe -> ");
break;
case SYS_read:
cprintf("read -> ");
break;
case SYS_kill:
cprintf("kill -> ");
break;
case SYS_exec:
cprintf("exec -> ");
break;
case SYS_fstat:
cprintf("fstat -> ");
break;
case SYS_chdir:
cprintf("chdir -> ");
break;
case SYS_dup:
cprintf("dup -> ");
break;
case SYS_getpid:
cprintf("getpid -> ");
break;
case SYS_sbrk:
cprintf("sbrk -> ");
break;
case SYS_sleep:
cprintf("sleep -> ");
break;
case SYS_uptime:
cprintf("uptime -> ");
break;
case SYS_open:
cprintf("open -> ");
break;
case SYS_write:
cprintf("write -> ");
break;
case SYS_mknod:
cprintf("mknod -> ");
break;
case SYS_unlink:
cprintf("unlink -> ");
break;
case SYS_link:
cprintf("link -> ");
break;
case SYS_mkdir:
cprintf("mkdir -> ");
break;
case SYS_close:
cprintf("close -> ");
break;
case SYS_date:
cprintf("date -> ");
break;
default:
panic("should never get here\n");
}
cprintf("%d\n", proc->tf->eax);
} else {
cprintf("%d %s: unknown sys call %d\n",
proc->pid, proc->name, num);
proc->tf->eax = -1;
}
}

运行结果

Date system call

实验要求

第二部分的主要任务是想xv6系统中添加并实现一个date系统调用,用以输出当前的UTC时间。

实验思路

要实现date系统调用主要是添加系统调用号和添加对应的系统调用函数,具体过程可以仿照uptime系统调用的实现。

实验步骤

使用grep命令筛选出出现uptime字样的文件和文件中所在行号,以便仿照uptime系统调用实现date系统调用:

在syscall.c中添加系统调用函数的外部声明,共有两处地方需要添加:

在syscall.h中添加系统调用号:

在sysproc.c中添加系统调用函数sys_date()的实现:

在user.h中添加用户态函数的定义:

在usys.S中添加用户态函数的实现:

由于我们还需要在用户空间来对内核提供的系统命令进行调用,新建用户程序date.c文件,写入以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#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();
}
// your code to print the time in any format you like...
printf(2, "The current UTC time: %d:%d:%d, %d/%d, %d\n", r.hour, r.minute, r.second, r.month, r.day, r.year);
printf(2, "The current Beijing time: %d:%d:%d, %d/%d, %d\n", r.hour+8, r.minute, r.second, r.month, r.day, r.year);
exit();
}

运行结果

由于北京时间与UTC时间相差8个小时,因此 输出的北京时间 = UTC时间 + 8小时,与实际情况相符,说明 date 这一系统调用添加成功。

坚持原创技术分享,您的支持将鼓励我继续创作!

热评文章