MIT 6.S081 操作系统课程系列2 System calls

MIT 6.S081 操作系统课程系列2 System calls


https://pdos.csail.mit.edu/6.828/2020/labs/syscall.html
本次实验需要读xv6手册第二章、4.3、4.4。看相关kernel代码。
理解system call的流程并实现一些system call。


物理资源的抽象


user模式和supervisor模式


kernel的规划


进程

进程的虚拟地址空间示意:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
_____________   
| trampoline | <- maxva
|____________|
| trapframe |
|____________|
| |
| |
| |
| |
| heap |
| |
| |
| |
| |
|____________|
| user stack |
|____________|
| |
| user text |
| user data |
|____________| <- 0


xv6的启动流程

  1. 上电。bootloader加载kernel进内存。地址为0x80000000。因为0x0到0x80000000包含io设备,所以放到0x80000000。
  2. machine模式。cpu执行entry.S里的_entry。此时硬件分页关闭,虚拟地址直接映射到物理地址。
  3. _entry起一个stack0让xv6能够跑c代码。sp指针指向stack0+4096。开始跑start.c里的start()函数。
  4. start()做一些machine模式特许的操作。
  5. 切换到supervisor模式。写main函数(kernel/main.c)的地址到mepc,直接返回到main函数。
  6. main()初始化各种设备和子系统。调用userinit()创建第一个进程。执行user/initcode.S。
  7. initcode.S执行exec(system call),启动init程序(user/init.c)。进入shell等待用户输入。

system call的c代码解析


实战

trace

  1. makefile里UPROGS加入trace
  2. user/user.h里加入trace的定义
  3. user/usys.pl里加入trace的定义
  4. kernel/syscall.h里加入trace新号
  5. kernel/proc.h的进程结构体里添加int类型trace_flag
  6. kernel/sysproc.c里加入sys_trace()
    sys_trace这个system call。获取参数用argint。给myproc()的trace_flag赋值即可。
  7. 修改fork函数。把parent的trace_flag传给child。
  8. 初始化进程的地方把trace_flag置0。
  9. 修改kernel/syscall.c。调用syscall后判断num和trace_flag,如果bit被打开,打印相关信息。

sysinfo

  1. 修改makefile
  2. user/user.h里加入sysinfo的定义(参照sysinfotest.c的使用方法)
  3. 参照trace的实现,添加其他定义。
  4. 实现sysinfo函数。

上次更新 2021-01-28