From ee6db185c07813faf18d28951d522425e076ce4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=A8=8B=E4=B8=9A=E7=BF=94?= <2000012158@stu.pku.edu.cn>
Date: Sat, 11 Nov 2023 22:28:36 +0800
Subject: [PATCH] completed

---
 Makefile            |  2 ++
 answers-syscall.txt |  6 ++++++
 kernel/defs.h       |  2 ++
 kernel/kalloc.c     | 18 ++++++++++++++++++
 kernel/proc.c       | 20 ++++++++++++++++++++
 kernel/proc.h       |  1 +
 kernel/syscall.c    | 33 +++++++++++++++++++++++++++++++++
 kernel/syscall.h    |  2 ++
 kernel/sysproc.c    | 31 +++++++++++++++++++++++++++++++
 time.txt            |  1 +
 user/user.h         |  3 +++
 user/usys.pl        |  2 ++
 12 files changed, 121 insertions(+)
 create mode 100644 answers-syscall.txt
 create mode 100644 time.txt

diff --git a/Makefile b/Makefile
index 365c91b..0e12e1e 100644
--- a/Makefile
+++ b/Makefile
@@ -188,6 +188,8 @@ UPROGS=\
 	$U/_grind\
 	$U/_wc\
 	$U/_zombie\
+	$U/_trace\
+	$U/_sysinfotest\
 
 
 
diff --git a/answers-syscall.txt b/answers-syscall.txt
new file mode 100644
index 0000000..cc356d1
--- /dev/null
+++ b/answers-syscall.txt
@@ -0,0 +1,6 @@
+1. usertrap(). 
+2. 7. 
+3. user mode. 
+4. lw a3, 0(zero); a3 register. 
+5. The kernel crashed due to loading an unused memory data at address 0. 
+6. initcode; 1. 
diff --git a/kernel/defs.h b/kernel/defs.h
index a3c962b..468eca2 100644
--- a/kernel/defs.h
+++ b/kernel/defs.h
@@ -63,6 +63,7 @@ void            ramdiskrw(struct buf*);
 void*           kalloc(void);
 void            kfree(void *);
 void            kinit(void);
+uint64          freemem_amount(void);
 
 // log.c
 void            initlog(int, struct superblock*);
@@ -106,6 +107,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_process_num(void);
 
 // swtch.S
 void            swtch(struct context*, struct context*);
diff --git a/kernel/kalloc.c b/kernel/kalloc.c
index 0699e7e..b833e87 100644
--- a/kernel/kalloc.c
+++ b/kernel/kalloc.c
@@ -80,3 +80,21 @@ kalloc(void)
     memset((char*)r, 5, PGSIZE); // fill with junk
   return (void*)r;
 }
+
+uint64
+freemem_amount(void)
+{
+  struct run *r;
+  uint64 amount = 0;
+
+  acquire(&kmem.lock);
+  r = kmem.freelist;
+
+  while(r) {
+    r = r->next;
+    amount += PGSIZE;
+  }
+  release(&kmem.lock);
+
+  return amount;
+}
\ No newline at end of file
diff --git a/kernel/proc.c b/kernel/proc.c
index 58a8a0b..b2ca398 100644
--- a/kernel/proc.c
+++ b/kernel/proc.c
@@ -169,6 +169,7 @@ freeproc(struct proc *p)
   p->killed = 0;
   p->xstate = 0;
   p->state = UNUSED;
+  p->mask = 0;
 }
 
 // Create a user page table for a given process, with no user memory,
@@ -320,6 +321,7 @@ fork(void)
 
   acquire(&np->lock);
   np->state = RUNNABLE;
+  np->mask = p->mask;
   release(&np->lock);
 
   return pid;
@@ -686,3 +688,21 @@ procdump(void)
     printf("\n");
   }
 }
+
+int
+get_process_num(void)
+{
+  struct proc *p;
+
+  int num = 0;
+
+  for(p = proc; p < &proc[NPROC]; p++){
+    acquire(&p->lock);
+    
+    if (p->state != UNUSED) 
+      num ++;
+
+    release(&p->lock);
+  }
+  return num;
+}
\ No newline at end of file
diff --git a/kernel/proc.h b/kernel/proc.h
index d021857..3a1057d 100644
--- a/kernel/proc.h
+++ b/kernel/proc.h
@@ -104,4 +104,5 @@ struct proc {
   struct file *ofile[NOFILE];  // Open files
   struct inode *cwd;           // Current directory
   char name[16];               // Process name (debugging)
+  uint64 mask;
 };
diff --git a/kernel/syscall.c b/kernel/syscall.c
index ed65409..b64e84f 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,34 @@ static uint64 (*syscalls[])(void) = {
 [SYS_link]    sys_link,
 [SYS_mkdir]   sys_mkdir,
 [SYS_close]   sys_close,
+[SYS_trace]   sys_trace,
+[SYS_sysinfo] sys_sysinfo,
+};
+
+static char *sysname[] = {
+[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 +169,9 @@ 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]();
+    if(p->mask & (((uint64)1) << num)) {
+      printf("%d: syscall %s -> %d\n", p->pid, sysname[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/sysproc.c b/kernel/sysproc.c
index 3b4d5bd..5796168 100644
--- a/kernel/sysproc.c
+++ b/kernel/sysproc.c
@@ -5,6 +5,8 @@
 #include "memlayout.h"
 #include "spinlock.h"
 #include "proc.h"
+#include "sysinfo.h"
+
 
 uint64
 sys_exit(void)
@@ -91,3 +93,32 @@ sys_uptime(void)
   release(&tickslock);
   return xticks;
 }
+
+uint64
+sys_trace(void)
+{
+  uint64 mask;
+
+  argint(0, (int*)&mask);
+
+  myproc()->mask = mask;
+  return 0;
+}
+
+uint64
+sys_sysinfo(void)
+{
+  struct sysinfo info;
+
+  uint64 addr;
+  argaddr(0, &addr); 
+
+  info.freemem = freemem_amount();
+  info.nproc = get_process_num();
+
+  if (copyout(myproc()->pagetable, addr, (char *)&info, sizeof(info)) < 0) {
+    return -1;
+  }
+
+  return 0;
+}
\ No newline at end of file
diff --git a/time.txt b/time.txt
new file mode 100644
index 0000000..1e8b314
--- /dev/null
+++ b/time.txt
@@ -0,0 +1 @@
+6
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");
-- 
GitLab