过程:
Add $U/_trace to UPROGS in Makefile
在user/user.h中添加 trace的声明
int trace(int);
在user/usys.pl添加, usys.pl会生成汇编usys.S,而这个usys.S会使用ecall进入内核
entry("trace");
在kernel/syscall.h中为trace添加一个号码
#define SYS_trace 22
在 kernel/sysproc.c 添加并实现 sys_trace(), 需要使用一个结构体proc (见 kernel/proc.h)。从用户空间获取system calls参数的方法在kernel/syscall.c, 可以在kernel/sysproc.c找到它们的使用实例。
uint64 sys_trace(void) { int mask; argint(0, &mask); struct proc* proc = myproc(); proc->tracemask = mask; return 0; }
修改 fork() 将proc中新的变量也复制到child里面
np->tracemask = p->tracemask;
修改kernel/syscall.c中的 syscall() ,添加一个保存了函数名的结构体,print语句
static char* syscallsname[] = { [SYS_fork] "fork", [SYS_exit] "exit", [SYS_wait] "wait", [SYS_pipe] "pipe", [SYS_read] "read", [SYS_kill] "kill", [SYS_exec] "exec", [SYS_fstat] "fstat", [SYS_chdir] "chdir", [SYS_dup] "dup", [SYS_getpid] "getpid", [SYS_sbrk] "sbrk", [SYS_sleep] "sleep", [SYS_uptime] "uptime", [SYS_open] "open", [SYS_write] "write", [SYS_mknod] "mknod", [SYS_unlink] "unlink", [SYS_link] "link", [SYS_mkdir] "mkdir", [SYS_close] "close", [SYS_trace] "trace", [SYS_sysinfo] "sys_sysinfo", }; 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](); // a0 store return value // start if(p->tracemask & (1<部分源码说明:%dn",p->pid,syscallsname[num],p->trapframe->a0); } // end } else { printf("%d %s: unknown sys call %dn", p->pid, p->name, num); p->trapframe->a0 = -1; } }
kernel/proc.h: 定义了一个结构体proc(还有其他结构体),用以保存进程的状态信息. 如给定p为该进程的proc结构体指针。则:
p->pagetable可得到该进程的虚拟页表。p->kstack可得到两个栈,每个进程均有用户栈和内核栈,用户模式下使用用户栈,仅当进程通过system call 或 interrupt进入内核时才能使用内核栈p->state可获取进程的状态 实验二 sysinfo
前面流程和trace一致,修改Makefile,在user/user.h,user/usys.pl,kernel/syscall.h添加信息。
sysinfo记录的是 可用进程数 和 空闲内存, 这两个属性封装在一个结构体(见kernel/sysinfo.h)
计算可用进程数nproc:
参考 kernel/proc.c 中的allocproc函数。 在 kernel/proc.c 中添加:
int proc_num(void) { struct proc *p; int num = 0; for(p = proc; p < &proc[NPROC]; p++) { if(p -> state != UNUSED) { num++; } } return num; }```计算空闲内存,参考kernel/kalloc.c中的函数kalloc,kernel/kalloc.c在文件末尾添加:
int freemem_size() { struct run *r; int num = 0; r = kmem.freelist; while(r) { num++; r = r->next; } return num * PGSIZE; }
在kernel/def.h中添加声明:
// for sys_info int freemem_size(void); int proc_num(void);
需要在内核中将这些信息返回到用户态,参考sys_fstat() (kernel/sysfile.c) and filestat() (kernel/file.c)中的copyout用法, 在sys_proc.c中添加:
uint64 sys_sysinfo(void) { struct sysinfo sys_info; sys_info.freemem = freemem_size(); sys_info.nproc = proc_num(); struct proc *p = myproc(); uint64 addr; if(argaddr(0, &addr) < 0) return -1; if(copyout(p->pagetable, addr, (char *)&sys_info, sizeof(sys_info)) < 0) return -1; return 0; }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)