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.
int getprocs(void);
in user/user.h
.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();
}
kernel/proc.c
to add the actual int 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;
}
kernel/syscall.h
like this: #define SYS_getprocs 22
.syscall.c
. Here I made two modifications:[SYS_getprocs] sys_getprocs,
to the static uint64 (*syscalls[])(void)
. I didn't understand exactly how this work but I added it anyway.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.
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.o
into Makefile
:
just add the line $K/getprocs.o
in OBJS
definition:
K=kernel
U=user
OBJS = \
...
$K/main.o \
$K/vm.o \
$K/proc.o \
$K/getprocs.o \ <-- just here, Warning, you not must add any character after '\' but a new line.
$K/swtch.o \
...