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