diff options
author | Mole Shang <[email protected]> | 2024-01-18 17:35:27 +0800 |
---|---|---|
committer | Mole Shang <[email protected]> | 2024-01-18 17:35:27 +0800 |
commit | 493159b9bb1a764926daa49fb09bff8f29e8e9e5 (patch) | |
tree | bcae49e20df0ab9d86dab9bd10226807cc432f88 | |
parent | 33ca12a4653752d179e6296c7ca2f91a626d30f3 (diff) | |
download | xv6-labs-syscall.tar.gz xv6-labs-syscall.tar.bz2 xv6-labs-syscall.zip |
lab syscall: finishsyscall
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | answers-syscall.txt | 9 | ||||
-rw-r--r-- | kernel/defs.h | 6 | ||||
-rw-r--r-- | kernel/kalloc.c | 14 | ||||
-rw-r--r-- | kernel/proc.c | 20 | ||||
-rw-r--r-- | kernel/proc.h | 1 | ||||
-rw-r--r-- | kernel/syscall.c | 38 | ||||
-rw-r--r-- | kernel/syscall.h | 2 | ||||
-rw-r--r-- | kernel/sysinfo.c | 24 | ||||
-rw-r--r-- | kernel/sysproc.c | 18 | ||||
-rw-r--r-- | time.txt | 1 | ||||
-rw-r--r-- | user/user.h | 3 | ||||
-rwxr-xr-x | user/usys.pl | 2 |
13 files changed, 141 insertions, 0 deletions
@@ -19,6 +19,7 @@ OBJS = \ $K/trampoline.o \ $K/trap.o \ $K/syscall.o \ + $K/sysinfo.o \ $K/sysproc.o \ $K/bio.o \ $K/fs.o \ @@ -193,6 +194,8 @@ UPROGS=\ $U/_primes\ $U/_find\ $U/_xargs\ + $U/_trace\ + $U/_sysinfotest\ diff --git a/answers-syscall.txt b/answers-syscall.txt new file mode 100644 index 0000000..ca0ce77 --- /dev/null +++ b/answers-syscall.txt @@ -0,0 +1,9 @@ +usertrap() +7 +SYS_exec +user mode +lw a3,0(zero) +a3 +no +yes, `scause` 0xd -> interrupt = 0, exception code = 13 -> instruction page fault (riscv-priviledged p71) +'initcode', 1 diff --git a/kernel/defs.h b/kernel/defs.h index a3c962b..c8eeef3 100644 --- a/kernel/defs.h +++ b/kernel/defs.h @@ -8,6 +8,7 @@ struct spinlock; struct sleeplock; struct stat; struct superblock; +struct sysinfo; // bio.c void binit(void); @@ -63,6 +64,7 @@ void ramdiskrw(struct buf*); void* kalloc(void); void kfree(void *); void kinit(void); +int get_freemem(void); // log.c void initlog(int, struct superblock*); @@ -106,6 +108,7 @@ void yield(void); int either_copyout(int user_dst, uint64 dst, void *src, uint64 len); int either_copyin(void *dst, int user_src, uint64 src, uint64 len); void procdump(void); +int get_nproc(void); // swtch.S void swtch(struct context*, struct context*); @@ -141,6 +144,9 @@ int fetchstr(uint64, char*, int); int fetchaddr(uint64, uint64*); void syscall(); +// sysinfo.c +int sys_info(uint64); + // trap.c extern uint ticks; void trapinit(void); diff --git a/kernel/kalloc.c b/kernel/kalloc.c index 0699e7e..c2fdb86 100644 --- a/kernel/kalloc.c +++ b/kernel/kalloc.c @@ -80,3 +80,17 @@ kalloc(void) memset((char*)r, 5, PGSIZE); // fill with junk return (void*)r; } + +int +get_freemem(void) +{ + int n; + struct run *r; + + acquire(&kmem.lock); + for (n = 0, r = kmem.freelist; r; r = r->next) + n++; + release(&kmem.lock); + + return n * PGSIZE; +} diff --git a/kernel/proc.c b/kernel/proc.c index 58a8a0b..5aa616f 100644 --- a/kernel/proc.c +++ b/kernel/proc.c @@ -299,6 +299,9 @@ fork(void) // copy saved user registers. *(np->trapframe) = *(p->trapframe); + // inherit trace_mask + np->trace_mask = p->trace_mask; + // Cause fork to return 0 in the child. np->trapframe->a0 = 0; @@ -686,3 +689,20 @@ procdump(void) printf("\n"); } } + +int +get_nproc(void) +{ + int n = 0; + struct proc *p; + + for(int i = 0; i < NPROC; i++) { + p = &proc[i]; + acquire(&p->lock); + if(p->state != UNUSED) + n++; + release(&p->lock); + } + + return n; +} diff --git a/kernel/proc.h b/kernel/proc.h index d021857..4a2ca6c 100644 --- a/kernel/proc.h +++ b/kernel/proc.h @@ -91,6 +91,7 @@ struct proc { int killed; // If non-zero, have been killed int xstate; // Exit status to be returned to parent's wait int pid; // Process ID + int trace_mask; // SYS_trace mask (1 << SYS_xxx) // wait_lock must be held when using this: struct proc *parent; // Parent process diff --git a/kernel/syscall.c b/kernel/syscall.c index ed65409..94ae997 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -101,6 +101,8 @@ extern uint64 sys_unlink(void); extern uint64 sys_link(void); extern uint64 sys_mkdir(void); extern uint64 sys_close(void); +extern uint64 sys_trace(void); +extern uint64 sys_sysinfo(void); // An array mapping syscall numbers from syscall.h // to the function that handles the system call. @@ -126,6 +128,35 @@ static uint64 (*syscalls[])(void) = { [SYS_link] sys_link, [SYS_mkdir] sys_mkdir, [SYS_close] sys_close, +[SYS_trace] sys_trace, +[SYS_sysinfo] sys_sysinfo, +}; + +// syscall name maps for SYS_trace: +static char *syscall_names[] = { +[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] "sysinfo", }; void @@ -139,6 +170,13 @@ syscall(void) // Use num to lookup the system call function for num, call it, // and store its return value in p->trapframe->a0 p->trapframe->a0 = syscalls[num](); + + // SYS_trace: match all the syscalls which number < mask asked + // p->trace_mask == 1 << SYS_xxx + if(p->trace_mask >> num) { + printf("%d: syscall %s -> %d\n", p->pid, syscall_names[num], p->trapframe->a0); + } + } else { printf("%d %s: unknown sys call %d\n", p->pid, p->name, num); diff --git a/kernel/syscall.h b/kernel/syscall.h index bc5f356..0dfedc7 100644 --- a/kernel/syscall.h +++ b/kernel/syscall.h @@ -20,3 +20,5 @@ #define SYS_link 19 #define SYS_mkdir 20 #define SYS_close 21 +#define SYS_trace 22 +#define SYS_sysinfo 23 diff --git a/kernel/sysinfo.c b/kernel/sysinfo.c new file mode 100644 index 0000000..c66324d --- /dev/null +++ b/kernel/sysinfo.c @@ -0,0 +1,24 @@ +#include "types.h" +#include "riscv.h" +#include "param.h" +#include "spinlock.h" +#include "defs.h" +#include "sysinfo.h" +#include "proc.h" + +// Get current system info +// addr is a user virtual address, pointing to a struct sysinfo. +int +sys_info(uint64 addr) { + struct proc *p = myproc(); + struct sysinfo info; + + // Fill nums into the sysinfo struct + info.freemem = get_freemem(); + info.nproc = get_nproc(); + + if(copyout(p->pagetable, addr, (char *)&info, sizeof(info)) < 0) + return -1; + return 0; +} + diff --git a/kernel/sysproc.c b/kernel/sysproc.c index 3b4d5bd..fd2e069 100644 --- a/kernel/sysproc.c +++ b/kernel/sysproc.c @@ -91,3 +91,21 @@ sys_uptime(void) release(&tickslock); return xticks; } + +uint64 +sys_trace(void) +{ + argint(0, &myproc()->trace_mask); + + return -(myproc()->trace_mask <= 1); +} + +uint64 +sys_sysinfo(void) +{ + uint64 si; // user pointer to struct sysinfo + + argaddr(0, &si); + return sys_info(si); +} + diff --git a/time.txt b/time.txt new file mode 100644 index 0000000..b8626c4 --- /dev/null +++ b/time.txt @@ -0,0 +1 @@ +4 diff --git a/user/user.h b/user/user.h index 4d398d5..14f69e5 100644 --- a/user/user.h +++ b/user/user.h @@ -1,4 +1,5 @@ struct stat; +struct sysinfo; // system calls int fork(void); @@ -22,6 +23,8 @@ int getpid(void); char* sbrk(int); int sleep(int); int uptime(void); +int trace(int); +int sysinfo(struct sysinfo*); // ulib.c int stat(const char*, struct stat*); diff --git a/user/usys.pl b/user/usys.pl index 01e426e..bc109fd 100755 --- a/user/usys.pl +++ b/user/usys.pl @@ -36,3 +36,5 @@ entry("getpid"); entry("sbrk"); entry("sleep"); entry("uptime"); +entry("trace"); +entry("sysinfo"); |