MIT6.s081_Lab2 syscall: System calls
MIT6.s081 Lab2:System calls
这次的实验主要是写两个System Call,分别是tracing和Sysinfo。tracing是对系统调用的跟踪,接收一个mask,来对系统调用进行过滤;Sysinfo用来收集系统的一些信息,比如剩余内存、进程的数量。文笔较烂,主要做记录,也希望能给读者一点启发。
1. tracing
因为是为了跟踪在‘mask’作用下的系统调用,每次进行系统调用的时候会进入syscall(),因此需要在syscall函数中将系统调用的名称打印出,我们容易获取到的是系统调用号,所以需要再添加一个数组,记录调用号对应的名称。
if (p->trace_mask & (1 << num)) {
printf("%d: syscall %s -> %d\n", p->pid, syscall_names[num], p->trapframe->a0);
}
还需要在proc结构体中添加mask,在初始化以及fork等处添加相关代码,维护mask。
uint64
sys_trace(void)
{
int mask;
if(argint(0, &mask) < 0)
return -1;
myproc() -> trace_mask = mask;
return 0;
}
这个实验主要是对整个系统调用过程的理解。
2. Sysinfo
这个需要知道struct sysinfo和copyout基本用法,剩下的就是写两个函数获取当前的进程数量和内存信息,然后放到sysinfo函数里即可。
获取剩余内存
uint64
get_free_memory(void) {
uint64 free_bytes = 0;
struct run *current_page;
acquire(&kmem.lock);
current_page = kmem.freelist;
while (current_page) {
free_bytes += 4096;
current_page = current_page->next;
}
release(&kmem.lock);
return free_bytes;
}
获取进程数量
uint16
get_proc_num(void)
{
struct proc *p;
uint16 proc_num = 0;
for(p = proc; p < &proc[NPROC]; p++) {
acquire(&p->lock);
if(p->state != UNUSED) {
proc_num++;
}
release(&p->lock);
}
return proc_num;
}
将获取的数据拷贝回用户空间
uint64
sys_sysinfo(void)
{
uint64 siaddr;
struct sysinfo si;
if(argaddr(0, &siaddr) < 0)
return -1;
si.freemem = get_free_memory();
si.nproc = get_proc_num();
if(copyout(myproc()->pagetable, siaddr, (char *)&si, sizeof(si)) < 0)
return -1;
return 0;
}

浙公网安备 33010602011771号