一、system call tracing
1 实验目的
写一个trace system call ,从而达到追踪进程调用的syscall的目的,输出为pid,system call name 以及return value。
trace的参数argv[1]为mask,32bits 无符号整型,第i位表示是否追踪第i个system call,追踪则为1,否则为0。
2 实验原理
进程在user space调用trace,trace执行ecall sys_trace进入到kernel space,在user space中,system call number存在register a7中,参数存在register a0中,进入kernel space时,进程将user space现场保存到p->trapframe中。在kernel space中,执行syscall函数,该函数检索p->trapframe->a7获得system call number,然后在执行kernel space中的sys_trace函数。最终将返回值存入到a0,回到user space。
3 主要代码
kernel space中的sys_trace函数,检索参数,并将参数存入到myproc()->mask中。
uint64
sys_trace(void)
{
uint32 n;
if(argint(0,(int*)(&n))<0)
return -1;
myproc()->mask=n;
return 0;
}
在syscall函数中,根据system call number 和mask值,判断是否要trace。
小trick:通过位运算的方式,判断第i位是否为1。
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]();
if(((1<<num)&p->mask)!=0){
printf("%d: syscall %s -> %d\n",p->pid,name[num],p->trapframe->a0);
}
} else {
printf("%d %s: unknown sys call %d\n",
p->pid, p->name, num);
p->trapframe->a0 = -1;
}
}
4 实验结果
二、sysinfo
1 实验目的
写一个sysinfo系统调用,得到freemem数和used process数。
2 主要代码
获得freemem数以及used process 数。这两个函数声明要加入到kernel/defs.h这个头文件中。
uint64
kfreemem(){
struct run *r;
uint64 n=0;
acquire(&kmem.lock);
r=kmem.freelist;
while(r){
n++;
r=r->next;
}
release(&kmem.lock);
return n*PGSIZE;
}
uint64 nproc(){
struct proc *p;
uint64 n=0;
for(p=proc;p<&proc[NPROC];p++){
acquire(&p->lock);
if(p->state!=UNUSED)
n++;
release(&p->lock);
}
return n;
}
kernel space中sys_sysinfo函数
uint64
sys_sysinfo(void)
{
struct sysinfo sinfo;
uint64 ip;
sinfo.freemem=kfreemem();
sinfo.nproc=nproc();
if(argaddr(0,&ip)<0)
return -1;
if(copyout(myproc()->pagetable,ip,(char*)&sinfo,sizeof(sinfo))<0)
return -1;
return 0;
}
3 实验结果