diff options
| -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"); | 
