Lab2 System Calls
开学!
实验开始前
1 | git fetch |
使用 gdb
- 查看 backtrace 的输出,哪个函数调用了 syscall
usertrap()
- 在 syscall 设置断点后,输入
backtrace
查看栈回溯
- p->trapframe->a7 的值是多少,值代表什么?
- 7,代表系统调用号 SYS_exec
p/x *p->trapframe
输出 p 的 trapframe 内容
- CPU 的上一个模式是什么?
- 用户模式
p/x $sstatus
输出 sstatus 寄存器的值,0x22- 在
kernel/riscv.h
中有定义:#define SSTATUS_SPP (1L << 8) // Previous mode, 1=Supervisor, 0=User
,也可以看给的文档 - 这里的 SPP 位为 0,因此上一个模式是用户模式
- 令
num = * (int *) 0;
,kernel 在哪条汇编指令 panic,哪个寄存器对应变量 numlw a3, 0(zero)
,a3- 查看 panic 时 spec 寄存器的值指向哪个汇编
- 为什么内核崩溃了?在内核地址空间 0 地址有映射吗?上面的 scause 值是否证实这一点?
- 因为尝试读取 0 地址,它没有有效映射
- 寄存器 scause 表示发生 trap 的原因,这里的 scause 是 0xd,查看文档可以知道,0xd 表示 Load page fault,合理
- 当内核 panic 时进程的名字是什么?进程 pid 是多少?
- “initcode”,1
一开始做因为寄存器的值不了解,还不太能看懂文档,没能理解,跳过了,有些答案是后面更新的
疑问
- 访问到 0 地址时为什么会跳转到 kernelvec 中
- scause、sepc、stval 的含义
更新:访问 0 发生了 trap,需要跳转到处理内核 trap 的位置,即 kerneltrap
,而在处理之前,先保存内核的状态,kernelvec
就是做这样的事情;scause 描述 trap 原因,sepc 保存发生 trap 时 pc 的值,stval 保存发生 trap 的值
System call tracing
在 user/trace.c
已经写好了程序,只需要实现系统调用即可
- 先在
user/user.h
加上原型,在user/usys.pl
加上 stub(存根),在kernel/syscall.h
加上系统调用号 - 在
kernel.c
的 proc 结构体加上一个新变量 trace_mask - 在
kernel/sysproc.c
加上sys_trace
,设置当前进程的 track_mask
1 | uint64 |
- 修改
kernel/proc.c
的fork
函数,将父进程的 tracemask 传给子进程
1 | np->trace_mask = p->trace_mask; |
- 修改
kernel/syscall.c
的syscall
函数,如果是 trace_mask 对应的系统调用号,就打印出来(里面还要添加一个字符串数组 syscallNames)
1 | ret = syscalls[num](); |
一个很简单的系统调用,仅仅是获取系统调用参数,然后将参数传给 p->trace_mask,在 syscall
函数中检查输出调用的系统调用,就可以实现,但是能学到很多细节
Sysinfo
这里我们要使用 copyout,因为系统调用函数位处于内核模式,需要进程的页表和虚拟地址来查找用户进程中变量的物理位置(比如 sysinfo 结构体),然后将内核的数据复制给用户进程
1 | uint64 |
写 get_freemem 时,观察 kalloc 函数,直接从 kmem.freelist 取一页内存返回,可以推测 kmem.freelist 包含所有可用的内存
1 | uint64 |
写 ger_nproc 时,观察 procinit 函数,在 proc[NPROC] 数据中遍历初始化,且其中含 state 变量
1 | uint64 |
记得在 sysproc.c 引入 sysinfo.h,在 defs.h 加上 get_freemem 和 get_nproc
Optional challenge exercises
打印出被追踪的系统调用的参数
每个系统调用参数个数记录在数组里,然后打印出来就好了
1 | if(p->trace_mask & 1<<num) { |
打印出来是这样的
1 | $ trace 32 grep hello README |
计算负载平均值并通过 sysinfo 导出
可以借用 Linux 的算法计算(懒)
Lab2 System Calls