Lab2
mit 6.s081 lab2
Lab2怎么说呢,总觉得挺奇怪的,第一次接触系统调用代码,有点小懵,一个trace就做了我1个多小时。
lab1的时候只添加函数还是挺友好的,就跟平常写代码一样,这个系统调用就绕来绕去的,贼麻烦,也算体验到工程代码的<<乐趣>>?
不过还是得称赞一下lab2得Hints,没有它感觉根本做不下去:::
System call tracing(moderate)
首先看一下Hints,先pass掉那些test用例,后面再看:
lab2提示and我的提示:
在Makefile的UPROGS中添加
$U/_trace这一步比较简单,就像lab1那样在makefile里面添加即可
运行
make qemu,您将看到编译器无法编译user/trace.c,因为系统调用的用户空间存根还不存在:将系统调用的原型添加到user/user.h,存根添加到user/usys.pl,以及将系统调用编号添加到kernel/syscall.h,Makefile调用perl脚本user/usys.pl,它生成实际的系统调用存根user/usys.S,这个文件中的汇编代码使用RISC-V的ecall指令转换到内核。一旦修复了编译问题(注:如果编译还未通过,尝试先*make clean*,再执行*make qemu*),就运行trace 32 grep hello README;但由于您还没有在内核中实现系统调用,执行将失败。这里就纯粹按照提示去干
首先到user/user.h添加一个 int trace(int); (仿照上面那些,看着就知道要干嘛了
然后到user/usys.pl添加存根 entry("trace");
最后到kernel/syscall.h添加 #define SYS_trace 22
编译完可以看到user/usys.S里面新增了
trace: li a7, SYS_trace ecall ret
在kernel/sysproc.c中添加一个
sys_trace()函数,它通过将参数保存到proc结构体(请参见kernel/proc.h)里的一个新变量中来实现新的系统调用。从用户空间检索系统调用参数的函数在kernel/syscall.c中,您可以在kernel/sysproc.c中看到它们的使用示例。修改
fork()(请参阅kernel/proc.c)将跟踪掩码从父进程复制到子进程。修改kernel/syscall.c中的
syscall()函数以打印跟踪输出。您将需要添加一个系统调用名称数组以建立索引。
跟着上面到第二步就可以 make qemu 进去看看了,然后输一下测试用例试试,就会出现 trace fail
接下来就是 三四五 这三步来真正写代码
第三步主要是实现sys_trace 函数:
首先需要按照提示的:它通过将参数保存到proc结构体(请参见kernel/proc.h)里的一个新变量中来实现新的系统调用。可以知道,需要在 proc.h里面的结构体添加个新变量:
然后按照提示就可以继续在 kernel/sysproc.c 里面添加一个 sys_trace 函数:
这个函数的实现就是说如果系统调用 sys_trace called,就将 traceMask 赋值为 命令行带进来的参数,如:
然后到第四步,在kernel/proc.c的 fork() 加一行语句将 跟踪掩码从父进程复制到子进程:
第五步:修改kernel/syscall.c中的syscall()函数以打印跟踪输出,按照提示需要先建立一个名称索引。(wc,第一次见到这种写法,属实牛皮
最后就是要修改 syscall()函数来输出了
finally : 有个通过的小细节啊,上面的printf中间全要用空格,我刚开始用 tab,test还给我报了三个错....
最后我自己总结一下调用的,因为写完这文章再回顾还是得继续看 Hints:
Makefile调用perl脚本user/usys.pl,它生成实际的系统调用存根user/usys.S ->
sh 调用 trace 指令 ->
trace.c 将 argv[1] 传入 user/user.h 的 int trace(int) ->
user/user.h的存根在user/usys.pl 的entry("trace"); 进入系统调用 ->
syscall()在if语句里面进入kernel/sysproc.c中,执行 sys_trace(),将argv[1]添加到myproc()->traceMask中 ->
进程状态就被trace标记上了,然后转回trace.c,执行exec ->
在exec源码中这个struct proc *p = myproc();是带有traceMask的 ->
然后一执行syscall就会被判断到,然后输出我们想要跟踪的状态,如果是fork了的话,也会通过我们在fork里面给子进程添加的traceMask进而跟踪子进程
可能总结的不对,之后学明白了再回来看看需不需要改
Sysinfo(moderate)
在Makefile add $U/_sysinfotest\
在user.h add
在usys.pl add entry("sysinfo");
在kernel/syscall.h添加 #define SYS_sysinfo 23
在sysproc.c添加:
在defs.h的不同位置添加上面两个函数,根据文件的注释就行
在kalloc.c添加:
我最开始是直接count++,发现test的时候错了,报的那个正确数是我得到的 4096倍,因此发现了PGSIZE的含义: #define PGSIZE 4096 // bytes per page
在proc.c添加:
其他一些需要的添加跟上面一样,如果要使用trace debug的话参照我上面的添加就行,感觉trace还是写的很鸡肋,在我debug的过程中没有产生任何作用,还得是老师的测试脚本
Last updated