Lab2 System Call
1. Preview
1.1 xv6-book Chap2
xv6-book的第二章和lecture3的内容类似,主要介绍了操作系统的组织结构,从物理资源的抽象、用户态/内核态、系统调用、微内核/宏内核以及代码层面展开
xv6-book的4.3、4.4节讲的是如何进行系统调用
1.2 code
了解xv6启动过程
_entry.S
中将stack0+4096
赋给栈指针寄存器sp
,使得其指向栈顶,然后call start
start
=> main
=>
userinit
=> initcode.S
=>
init.c
2 System call tracing
trace
是一个工具,能够记录指定的系统调用。
1 |
|
1 |
|
首先需要明确的是trace
也是一个系统调用,所以就需要大概明白从用户态调用trace
工具到内核调用对应的系统调用的过程。
根据手册的指示大概能够推测出来
1、在命令行中输入:trace 32 grep hello README
后,实际上是执行 /user/trace.c 文件。过程就是 先执行 trace
函数,然后再执行后面的命令。
2、这个 trace 函数是需要在 /user/user.h
文件中定义原型的,之后好像就找不到对应的实现了。其实之后的实现是在内核态了,需要先陷入内核,手册中说要在
/user/usys.pl 中定义一个 stub: entry("trace")
,这个stub会在
user/usys.S 生成一段汇编代码:进行系统调用。
3、其中的ecall
指令就会调用 /kernel/syscall.c 中的
syscall
函数,执行对应的系统调用函数 sys_
然后就可以开始根据手册的提示写代码了...
- 在 kernel/sysproc.c 中增加 sys_trace() 函数
- 要在 proc 结构体中增加一个新的变量存储 trace 的参数
- 修改 syscall() 函数来打印 trace 输出
- 修改 fork() 函数使得 trace 的参数从父进程拷贝到子进程
1 |
|
1 |
|
测试结果
注意第四个测试有可能会超时,需要修改 gradelib.py 文件的第 428 行 扩大时间限制
3 Sysinfo
还是实现一个系统调用,在内核填上 struct sysinfo
的两个字段,并拷贝回用户空间,主要过程:
- 像
trace
那样,在对应位置增加系统调用所需的相关信息。 - 在
kernel/proc.c
中增加一个统计not UNUSED process
的函数 - 在
kernel/kalloc.c
中增加一个统计free memory
的函数 - 理解
copyout
函数,在系统调用中将struct sysinfo
从内核空间 拷贝入 用户空间
核心代码
1 |
|
统计 不是 UNUSED 的 进程数量,只需要遍历 proc 数组即可。
1 |
|
统计 free memory,需要读一下 kalloc.c
的代码,会发现 在
kalloc
函数中,如果 kmem.freelist
不为空的话就会分配一个 PGSIZE
的内存空间,所以只需要统计
kmem.freelist
链表长度即可。
1 |
|
测试结果