其他分享
首页 > 其他分享> > MIT6.S081学习总结-lab2: system calls

MIT6.S081学习总结-lab2: system calls

作者:互联网

lab2 主要实现两个系统调用

添加系统调用过程

  1. user/user.h里添加系统调用函数,这个lab需要添加两个系统调用,下图中最后两个:trace 和 sysinfo
    在这里插入图片描述
  2. user/usys.pl里添加一个entry,这个文件会生成user/usys.S,就是系统调用的具体实现,之后会使用ecall指令跳转到相应的系统调用去执行。
    在这里插入图片描述
  3. kernel/syscall.h添加系统调用的编号
    在这里插入图片描述
  4. kernel/syscall.c添加系统调用的函数映射,syscalls这个数组存放了所有指向系统调用的实现函数指针

在这里插入图片描述在这里插入图片描述

  1. 最后就是实现系统调用函数

1.trace

实现trace,输入mask,需要trace对应位为1的系统调用,每个系统调用对应一个数字,如系统调用fork对应数字为SYS_fork,如果要trace fork,那么mask & (1 << SYS_fork) = 1即可。trace输出 进程号、系统调用函数名、系统调用返回值。

$ trace 32 grep hello README
3: syscall read -> 1023
3: syscall read -> 966
3: syscall read -> 70
3: syscall read -> 0
$
$ trace 2147483647 grep hello README
4: syscall trace -> 0
4: syscall exec -> 3
4: syscall open -> 3
4: syscall read -> 1023
4: syscall read -> 966
4: syscall read -> 70
4: syscall read -> 0
4: syscall close -> 0

具体实现过程:

  1. 按照之前过程添加 trace系统调用
  2. trace需要每个进程保存mask,因此在kernel/proc.h 中proc结构体添加mask,这里只简单的用了int,因为目前系统调用20几个,31位够用。如果考虑可扩展性的话,可以使用数组。
    在这里插入图片描述
  3. 有了这个标志,可以直接写出trace的实现了。在kernel/sysproc.c添加sys_trace函数,函数里只需要将当前进程的tracemask置为mask即可。
    在这里插入图片描述
  4. 子进程也需要修改mask,修改kernel/proc.c里的fork,子进程继承父进程的tracemask
    在这里插入图片描述
  5. 最后就是输出,kernel/syscall.c的syscall函数添加输出,因为只能得到系统调用对应的数字编号,因此还需要添加该编号到名字的映射。
    在这里插入图片描述在这里插入图片描述

2.sysinfo

sysinfo用于得到为分配的内存字节数以及不处于UNUSED状态的进程数。
在这里插入图片描述实现:

  1. 像之前一样添加系统调用sysinfo.
  2. 获取未分配的内存字节数,在kernel/kalloc.c里添加,kmem.freelist表示空闲页块头结点,因此遍历到末尾即可,最后需要乘上页大小。
    在这里插入图片描述
  3. 获取不为 UNUSED状态的进程数,在kernel/proc.c里添加,也是遍历一遍就行。
    在这里插入图片描述
  4. 最后就是添加sysinfo系统调用,我是在kernel/sysproc.c里添加的,需要加sysinfo.h头文件,调用上面两个函数获取fennmemnproc,之后用copyout将其从内核空间复制到用户空间。
    在这里插入图片描述

总结

刚开始做没有什么头绪,之后看源码,了解了大致系统调用过程后再回头看看实现也不是很复杂。

标签:kernel,调用,trace,calls,MIT6,系统,system,syscall,添加
来源: https://blog.csdn.net/laplacebh/article/details/117558563