Sysinfo (moderate)
系统调用sysinfo,它收集有关正在运行的系统的信息。
在Makefile的UPROGS中添加$U/_sysinfotest
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -150,7 +150,7 @@ UPROGS=\
$U/_wc\
$U/_zombie\
$U/_trace\
$U/_sysinfotest\
ifeq ($(LAB),trap)
UPROGS += \
要在user/user.h中声明sysinfo()的原型
需要预先声明struct sysinfo的存在:
c
struct sysinfo;
int sysinfo(struct sysinfo *);
即
diff --git a/user/user.h b/user/user.h
--- a/user/user.h
+++ b/user/user.h
@@ -1,5 +1,6 @@
struct stat;
struct rtcdate;
struct sysinfo;
// system calls
int fork(void);
@@ -24,6 +25,7 @@ char* sbrk(int);
int sleep(int);
int uptime(void);
int trace(int);
int sysinfo(struct sysinfo *);
// ulib.c
int stat(const char*, struct stat*);
当运行make qemu时,user/sysinfotest.c将会编译失败
遵循和上一个作业一样的步骤添加sysinfo系统调用
diff --git a/user/usys.pl b/user/usys.pl
--- a/user/usys.pl
+++ b/user/usys.pl
@@ -36,4 +36,5 @@ entry("getpid");
entry("sbrk");
entry("sleep");
entry("uptime");
entry("trace");
\ No newline at end of file
entry("trace");
entry("sysinfo");
\ No newline at end of file
diff --git a/kernel/syscall.h b/kernel/syscall.h
--- a/kernel/syscall.h
+++ b/kernel/syscall.h
@@ -20,4 +20,5 @@
#define SYS_link 19
#define SYS_mkdir 20
#define SYS_close 21
#define SYS_trace 22
\ No newline at end of file
#define SYS_trace 22
#define SYS_sysinfo 23
\ No newline at end of file
diff --git a/kernel/syscall.c b/kernel/syscall.c
--- a/kernel/syscall.c
+++ b/kernel/syscall.c
@@ -105,6 +105,7 @@ extern uint64 sys_wait(void);
extern uint64 sys_write(void);
extern uint64 sys_uptime(void);
extern uint64 sys_trace(void);
extern uint64 sys_sysinfo(void);
static uint64 (*syscalls[])(void) = {
[SYS_fork] sys_fork,
@@ -129,6 +130,7 @@ static uint64 (*syscalls[])(void) = {
[SYS_mkdir] sys_mkdir,
[SYS_close] sys_close,
[SYS_trace] sys_trace,
[SYS_sysinfo] sys_sysinfo,
};
static char *syscall_names[] = {
一旦修复了编译问题,就运行sysinfotest
;但由于您还没有在内核中实现系统调用,执行将失败。
sysinfo需要将一个struct sysinfo复制回用户空间
请参阅sys_fstat()(kernel/sysfile.c)和filestat()(kernel/file.c)以获取如何使用copyout()执行此操作的示例。
diff --git a/kernel/sysproc.c b/kernel/sysproc.c
--- a/kernel/sysproc.c
+++ b/kernel/sysproc.c
@@ -6,6 +6,10 @@
#include "memlayout.h"
#include "spinlock.h"
#include "proc.h"
#include "sysinfo.h"
int get_nproc();
int get_freemen();
uint64
sys_exit(void)
@@ -108,3 +112,23 @@ sys_trace(void)
p->trace_mask=mask;
return 0;
}
uint64
sys_sysinfo(void){
struct proc *p = myproc();
struct sysinfo st;
uint64 addr;
st.nproc=get_nproc();
st.freemem=get_freemen();
//参阅sys_fstat()(kernel/sysfile.c)
if(argaddr(0, &addr) < 0)//获取指向结构体的指针,并存储在 st 变量中
return -1;
//参阅filestat()(kernel/file.c)
if(copyout(p->pagetable, addr, (char *)&st, sizeof(st)) < 0)//将 st 结构体的内容从内核空间复制到用户空间的指定地址 addr
return -1;
return 0;
}
\ No newline at end of file
要获取空闲内存量,在kernel/kalloc.c中添加一个函数
diff --git a/kernel/kalloc.c b/kernel/kalloc.c
--- a/kernel/kalloc.c
+++ b/kernel/kalloc.c
@@ -80,3 +80,18 @@ kalloc(void)
memset((char*)r, 5, PGSIZE); // fill with junk
return (void*)r;
}
int get_freemen(void){
int count=0;
struct run *r;
acquire(&kmem.lock);
r = kmem.freelist;
while(r){
r=r->next;
count++;
}
release(&kmem.lock);
return count * PGSIZE;
}
\ No newline at end of file
要获取进程数,在kernel/proc.c中添加一个函数
diff --git a/kernel/proc.c b/kernel/proc.c
--- a/kernel/proc.c
+++ b/kernel/proc.c
@@ -696,3 +696,16 @@ procdump(void)
printf("\n");
}
}
int get_nproc(void){
int count=0;
struct proc *p;
for(p = proc; p < &proc[NPROC]; p++) {
acquire(&p->lock);
if(p->state != UNUSED) {
count++;
}
release(&p->lock);
}
return count;
}
\ No newline at end of file