MIT 6.S081 Operating System Enginerring Lab2 System calls
这里给出Lab2 System calls的解析。
学习资料:
- https://pdos.csail.mit.edu/6.828/2020/schedule.html
- https://mit-public-courses-cn-translatio.gitbook.io/mit6-s081/
- https://th0ar.gitbooks.io/xv6-chinese/content/
- https://www.bilibili.com/video/BV19k4y1C7kA
参考资料:
准备工作
修改测评脚本:
将
#!/usr/bin/env python
修改为:
#!/usr/bin python
测试命令由
./grade-lab-syscall trace
修改为:
sudo python3 grade-lab-syscall trace
System call tracing (moderate)
调用过程:
- trace.c设置调用trace
- trace调用sys_trace
- 设置mask
- fork产生子进程
- syscall调用子进程
流程:
在/xv6-labs-2020/kernel/proc.h的结构proc中添加mask字段记录需要trace的进程;
在/xv6-labs-2020/kernel/sysproc.c中添加如下函数,该函数的作用是解析参数,设置mask:
// add uint64 sys_trace(void){ uint64 p; // 获得参数 if(argaddr(0, &p) < 0) return -1; myproc()->mask = p; return 0; }
修改/xv6-labs-2020/kernel/syscall.c的函数syscall:
void syscall(void) { int num; struct proc *p = myproc(); num = p->trapframe->a7; if(num > 0 && num < NELEM(syscalls) && syscalls[num]) { p->trapframe->a0 = syscalls[num](); // add if ((1 << num) & p->mask){ printf("%d: syscall %s -> %d\n", p->pid, sysnames(num), p->trapframe->a0); } } else { printf("%d %s: unknown sys call %d\n", p->pid, p->name, num); p->trapframe->a0 = -1; } }
测试:
sudo python3 grade-lab-syscall trace
make: 'kernel/kernel' is up to date.
== Test trace 32 grep == trace 32 grep: OK (1.2s)
== Test trace all grep == trace all grep: OK (0.9s)
== Test trace nothing == trace nothing: OK (1.1s)
== Test trace children == trace children: OK (10.3s)
Sysinfo (moderate)
调用过程:
- sysinfotest.c设置调用sysinfo
- sysinfo调用sys_sysinfo
- sys_sysinfo计算freemem以及nproc
流程:
在/xv6-labs-2020/kernel/kalloc.c中添加函数:
// add uint64 freemem(void) { struct run *r; r = kmem.freelist; uint64 cnt = 0; while (r){ cnt += 4096; r = r->next; } return cnt; }
在/xv6-labs-2020/kernel/proc.c中添加函数:
// add uint64 nproc(void) { struct proc *p; uint64 cnt = 0; for(p = proc; p < &proc[NPROC]; p++) { if(p->state != UNUSED) { cnt++; } } return cnt; }
在/xv6-labs-2020/kernel/sysproc.c中添加函数:
// add uint64 sys_sysinfo(void){ // 参数地址 uint64 addr; if(argaddr(0, &addr) < 0) return -1; // 保存信息 struct sysinfo sys_info; sys_info.freemem = freemem(); sys_info.nproc = nproc(); if (copyout(myproc()->pagetable, addr, (char *)&sys_info, sizeof(sys_info)) < 0){ return -1; } return 0; }
说明:
- copyout函数将pagetable中sys_info位置开始的sizeof(sys_info)字节复制到addr地址,即将kernel中数据复制给user。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Doraemonzzz!
评论
ValineLivere