I was playing with the Xv6 OS lab and trying to implement a simple syscall getprocs() that returns the number of processes currently running. I finished the work pretty soon but I kept getting the following error message when I was trying to do make qemu:
riscv64-unknown-elf-ld: warning: cannot find entry symbol _entry; defaulting to 0000000080000000
riscv64-unknown-elf-ld: kernel/syscall.o: in function `syscall':
/xv6-labs-2020/kernel/syscall.c:143: undefined reference to `sys_getprocs'
riscv64-unknown-elf-ld: kernel/syscall.o: in function `.LANCHOR0':
syscall.c:(.rodata+0xc8): undefined reference to `sys_getprocs'
make: *** [Makefile:94: kernel/kernel] Error 1
Here's what I did.
- I declared a user function
int getprocs(void);inuser/user.h. - I then created a new file
kernel/getprocs.c, where the system call interface is implemented as the following:
#include "types.h"
#include "param.h"
#include "memlayout.h"
#include "riscv.h"
#include "spinlock.h"
#include "proc.h"
#include "defs.h"
#include "syscall.h"
extern int get_procs(void);
uint64
sys_getprocs(void)
{
return get_procs();
}
- Following this, I went to
kernel/proc.cto add the actualint get_procs(void)that counts all the used processes in the system:
int
get_procs(void)
{
int num_procs = 0;
struct proc *p;
for(p = proc; p < &proc[NPROC]; p++) {
acquire(&p->lock);
if(p->state != UNUSED) num_procs++;
release(&p->lock);
}
return num_procs;
}
- I assigned a new syscall number for my new function in
kernel/syscall.hlike this:#define SYS_getprocs 22. - Having assigned a new syscall number, I went to modify the system call table in
syscall.c. Here I made two modifications:
- add
[SYS_getprocs] sys_getprocs,to thestatic uint64 (*syscalls[])(void). I didn't understand exactly how this work but I added it anyway. - within function
void syscall(), I changed it to:
void
syscall(void)
{
int num;
struct proc *p = myproc();
num = p->trapframe->a7;
if(num == SYS_getprocs) p->trapframe->a0 = sys_getprocs();
else if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
p->trapframe->a0 = syscalls[num]();
} else {
printf("%d %s: unknown sys call %d\n",
p->pid, p->name, num);
p->trapframe->a0 = -1;
}
}
This should handle the newly added system call.
- Finally, I added a new mapping in
user/usys.pl:entry("getprocs");
I reviewed over and over again, still clueless where it went wrong. Any help would be appreciated!
You just forgot to ask for compilation of
getprocs.ointoMakefile:just add the line
$K/getprocs.oinOBJSdefinition: