Lab system calls
本文记录了 Lab: system calls 的实验过程
Lab: system calls
进入 xv6-labs-2020 目录, 执行
1 | git fetch |
System call tracing (moderate)
实验描述
实现一个
trace(int mask)
的系统调用。它的参数为mask
,mask
指定了哪些系统调用会被打印。例如,为了跟踪fork
系统调用,程序可以调用trace(1 << SYS_fork)
(其中,SYS_fork
定义在 kernel/syscall.h 中,表示fork
系统调用的编号)。修改 xv6 kernel 代码,使得如果某一个系统调用的编号在 mask 中对应的位为 1 时,在系统调用返回前,将该信息打印出来。每一行应该包含进程的 id,系统调用的名字以及返回值。
提示
根据 Lab 的教程,仔细阅读下面六个文件中相关的代码
- The user-space code for systems calls is in user/user.h and user/usys.pl
- The kernel-space code is kernel/syscall.h, kernel/syscall.c
- The process-related code is kernel/proc.h and kernel/proc.c
然后在根据提示修改对应文件中的代码。
实验步骤
打开目录中的 Makefile 文件,在 UPROGS 中添加:
$U/_trace
对 trace 进行定义。首先在 user/user.h 文件中添加
trace()
系统调用的声明
1 | // system calls |
在 user/usys.pl 中添加 trace()
的入口
1 | entry("trace"); |
在 kernel/syscall.h 中给它增加一个编号
1 |
- 在 kernel/sysproc.c 文件中添加函数
sys_trace()
,它的功能是读取trace()
传进来的参数mask
,然后保存到proc
结构体(定义在 kernel/proc.h)中的新增的变量中。
1 | struct proc { |
1 | // kernel/sysproc.c |
- 在
fork()
函数中(定义在 kernel/proc.c),将父进程的 mask 赋给子进程。
1 | np->mask = p->mask; |
- 修改 kernel/syscall.c 文件中的
syscall()
函数,打印需要输出的信息。
1 | ... |
总结
由于
mask
没理解清楚,导致打印了很多没用的信息。比如,mask = 2 = $(10)_2$ = (1 << 1),说明我们只需要跟踪 fork 这个系统调用(fork 系统调用的编号为 1)。mask = 32 = $(100000)_2$ = (1 << 5),说明我们只需要跟踪 read 这个系统调用。当 mask = 2147583647 = $2^{31}-1$,即 31 个 1,所以我们跟踪所有进程。即:mask 的二进制数从左向右数(最左边为第 0 位),第 n 位为 1 时,说明我们要打印第 n 个系统调用的信息。
Sysino
实验描述
该实验需要我们实现一个 sysinfo 的系统调用,它将收集系统的信息。它接收一个指向
struct sysinfo
(kernel/sysinfo.h)的指针。然后会将当前系统的剩余内存的字节数保存在字段 freemem 中,设置 nproc 为进程状态不为 UNUSED 的个数。
实验步骤
打开目录中的 Makefile 文件,在 UPROGS 中添加:
$U/_sysinfo
对
sysinfo
进行定义。首先在 user/user.h 文件中添加 sysinfo 系统调用以及sysinfo
结构体的声明
1 | struct sysinfo; |
在 user/usys.pl 中添加 sysinfo()
的入口
1 | entry("sysinfo"); |
在 kernel/syscall.h 中给它增加一个编号
1 |
- 在 kernel/defs.h 声明函数的原型(将下面函数声明添加到文件中的对应位置)
1 | // kalloc.c |
- 函数的实现
1 | // 在 kalloc.c 文件中添加函数的实现 |
1 | // 在 proc.c 文件中添加函数的实现 |
- 在 kernel/sysfile.c 中实现
sys_sysinfo()
1 |
|
- 最后在 kernel/syscall.c 文件中添加
1 | ... |
总结
一定要仔细阅读、理解提示中让你看的源码文件
测试
1 | ./grade-lab-syscall trace |
1 | ./grade-lab-syscall sysinfotest |
1 | make grade |