Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion xv6-os/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ entryother
initcode
initcode.out
kernelmemfs
mkfs
mkfs/mkfs
kernel/kernel
user/usys.S
.gdbinit
Expand Down
2 changes: 2 additions & 0 deletions xv6-os/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ UPROGS=\
$U/_alloctest\
$U/_cowtest\
$U/_lazytests\
$U/_pingpong\
$U/_sysinfo\

fs.img: mkfs/mkfs README $(UPROGS)
mkfs/mkfs fs.img README $(UPROGS)
Expand Down
3 changes: 3 additions & 0 deletions xv6-os/kernel/defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ 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 dump(void);
int dump2(int pid, int reg, uint64 return_value_user);
int get_sysinfo(uint64 user_addr);

// swtch.S
void swtch(struct context*, struct context*);
Expand Down
13 changes: 13 additions & 0 deletions xv6-os/kernel/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ struct {
struct file file[NFILE];
} ftable;

int count_open_files(void) {
int count = 0;
acquire(&ftable.lock);
for (int i = 0; i < NFILE; i++) {
if (ftable.file[i].ref > 0) {
count++;
}
}
release(&ftable.lock);

return count;
}

void
fileinit(void)
{
Expand Down
3 changes: 3 additions & 0 deletions xv6-os/kernel/file.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#define NDIRECT 12
struct file {
struct spinlock lock;
enum { FD_NONE, FD_PIPE, FD_INODE, FD_DEVICE } type;
int ref; // reference count
char readable;
Expand Down Expand Up @@ -36,5 +38,6 @@ struct devsw {
};

extern struct devsw devsw[];
int count_open_files(void);

#define CONSOLE 1
97 changes: 96 additions & 1 deletion xv6-os/kernel/proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
#include "memlayout.h"
#include "riscv.h"
#include "spinlock.h"
#include "sleeplock.h"
#include "proc.h"
#include "defs.h"
#include "file.h"
#include "sysinfo.h"

struct cpu cpus[NCPU];

struct proc proc[NPROC];

struct proc *initproc;

int nextpid = 1;
Expand Down Expand Up @@ -693,3 +695,96 @@ procdump(void)
printf("\n");
}
}

int dump(void) {
struct proc *p = myproc();
struct trapframe *tf = p->trapframe;

uint64 regs[10];

regs[0] = tf->s2;
regs[1] = tf->s3;
regs[2] = tf->s4;
regs[3] = tf->s5;
regs[4] = tf->s6;
regs[5] = tf->s7;
regs[6] = tf->s8;
regs[7] = tf->s9;
regs[8] = tf->s10;
regs[9] = tf->s11;

for (int i = 0; i < 10; i++) {
printf("s%d = %d\n", i + 2, (uint32)regs[i]);
}

return 0;
}

int dump2(int pid, int reg, uint64 return_value_user) {
struct proc *p = myproc();
struct proc *target_proc = 0;

// check for reg num (only s2..s11 are dumpable)
if (reg < 2 || reg > 11) {
return -3; // incorrect reg num
}

for (struct proc *proc_entry = proc; proc_entry < &proc[NPROC]; proc_entry++) {
acquire(&proc_entry->lock); // spinlock

if (proc_entry->pid == pid) {
target_proc = proc_entry;
// check for access rights
if (target_proc != p && target_proc->parent != p) {
release(&target_proc->lock);
return -1; // don't have enough access rights
}

uint64 reg_value;
if (reg >= 2 && reg <= 11) {
reg_value = *(&target_proc->trapframe->s2 + (reg - 2));
}

release(&target_proc->lock);

if (copyout(p->pagetable, return_value_user, (char *)&reg_value, sizeof(uint64)) < 0) {
return -4; // data write fail
}

return 0;
}

release(&proc_entry->lock);
}

return -2; // no process found with this pid
}

int
get_sysinfo(uint64 user_addr) {
struct proc *p = myproc();
struct sysinfo info;

info.procs_cnt=0;
info.open_files=0;
info.free_ram=0;
info.used_ram=0;

// count procs
for (struct proc *proc_entry = proc; proc_entry < &proc[NPROC]; proc_entry++) {
acquire(&proc_entry->lock);
if (proc_entry->state != UNUSED) {
info.procs_cnt++;
}
release(&proc_entry->lock);
}

// count open files
info.open_files=count_open_files();

if (copyout(p->pagetable, user_addr, (char *)&info, sizeof(info)) < 0) {
return -1; // data write fail
}

return 0; //Success
}
5 changes: 1 addition & 4 deletions xv6-os/kernel/proc.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ struct context {
uint64 s8;
uint64 s9;
uint64 s10;
uint64 s11;
};

// Per-CPU state.
uint64 s11; }; // Per-CPU state.
struct cpu {
struct proc *proc; // The process running on this cpu, or null.
struct context context; // swtch() here to enter scheduler().
Expand Down
3 changes: 3 additions & 0 deletions xv6-os/kernel/spinlock.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// Mutual exclusion lock.
#ifndef _SYS_SPINLOCK_H_
#define _SYS_SPINLOCK_H_
struct spinlock {
uint locked; // Is the lock held?

Expand All @@ -7,3 +9,4 @@ struct spinlock {
struct cpu *cpu; // The cpu holding the lock.
};

#endif // _SYS_SPINLOCK_H_
9 changes: 7 additions & 2 deletions xv6-os/kernel/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@

// Fetch the uint64 at addr from the current process.
int
fetchaddr(uint64 addr, uint64 *ip)
{
fetchaddr(uint64 addr, uint64 *ip) {
struct proc *p = myproc();
if(addr >= p->sz || addr+sizeof(uint64) > p->sz) // both tests needed, in case of overflow
return -1;
Expand Down Expand Up @@ -101,6 +100,9 @@ extern uint64 sys_unlink(void);
extern uint64 sys_link(void);
extern uint64 sys_mkdir(void);
extern uint64 sys_close(void);
extern uint64 sys_dump(void);
extern uint64 sys_dump2(void);
extern uint64 sys_info(void);

// An array mapping syscall numbers from syscall.h
// to the function that handles the system call.
Expand All @@ -126,6 +128,9 @@ static uint64 (*syscalls[])(void) = {
[SYS_link] sys_link,
[SYS_mkdir] sys_mkdir,
[SYS_close] sys_close,
[SYS_dump] sys_dump,
[SYS_dump2] sys_dump2,
[SYS_info] sys_info,
};

void
Expand Down
3 changes: 3 additions & 0 deletions xv6-os/kernel/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@
#define SYS_link 19
#define SYS_mkdir 20
#define SYS_close 21
#define SYS_dump 22
#define SYS_dump2 23
#define SYS_info 24
11 changes: 11 additions & 0 deletions xv6-os/kernel/sysinfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef _SYSINFO_H_
#define _SYSINFO_H_

struct sysinfo {
int procs_cnt;
int open_files;
int used_ram;
int free_ram;
};

#endif // _SYSINFO_H_
30 changes: 30 additions & 0 deletions xv6-os/kernel/sysproc.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,33 @@ sys_uptime(void)
release(&tickslock);
return xticks;
}

uint64
sys_dump(void)
{
return dump();
}

uint64
sys_dump2(void)
{
int pid;
int reg;
uint64 ret_val;

argint(0, &pid);
argint(1, &reg);
argaddr(2, &ret_val);

return dump2(pid, reg, ret_val);
}

uint64
sys_info(void)
{
uint64 user_addr;

argaddr(0, &user_addr);

return get_sysinfo(user_addr);
}
Loading
Loading