进入lab2 syscall,这次的任务是写两个系统调用。
第一个是trace,功能是把程序执行过程中的系统调用都展示出来。trace shell命令已经写好了,在user/trace.c
里面,看看就好,不用修改这个文件。
首先,老老实实按照lab的指示,阅读xv6 book的第二章,还有第四章的4.3和4.4 。这里面一个重点是kernel/proc.h
里面的proc结构体,其实它就是xv6的进程控制块(PCB Process Control Block,当年在书上学来学去很多遍,不如在代码见识一次)。你需要扩展它,增加一个值用来记录trace mask。你需要的很多信息也都在这个结构体里面。
照葫芦画瓢,在其他syscall的定义文件里,Makefile、kernel/syscall.h、kernel/syscall.c、user/user.h、user/usys.pl里面统统加上trace相关的声明,照着每个文件的格式写就行。
然后功能分布在kernel/proc.c, kernel/syscall.c, kernel/sysproc.c里面。proc.c主要是把trace mask从父进程拷贝到子进程。syscall.c负责打印trace信息。sysproc.c则包含了sys_trace的系统调用本体,逻辑很简单,就是把参数存到proc结构体新增的成员变量里。
也许你需要这个表
char* syscall_names[] = { "xxx", "fork", "exit", "wait", "pipe", "read", "kill", "exec", "fstat", "chdir", "dup", "getpid", "sbrk", "sleep", "uptime", "open", "write", "mknod", "unlink", "link", "mkdir", "close", "trace", "sysinfo", };
第二个是sysinfo。还是要注意在各个头文件里加好函数声明。在kernel/kalloc.c
里定义一个空闲内存的统计函数,很简单,就是遍历那个全局链表kmem,统计个数,然后乘以PGSIZE。在kernel/proc.c
里定义一个统计进程状态不等于UNUSED
的进程个数,遍历全局变量proc数组一个个判断、累加。至于把struct sysinfo从内核拷贝到用户空间,直接在代码库里搜索copyout
有大量范例,照抄即可,easy peasy。