Xv6 - Adding A System Call
Xv6 - Adding A System Call
Background
User mode
● Least privilege
● User processes run in this mode
● Uses paging with pagetable corresponding to running user process
Machine mode
● Highest privilege
● Bootloader, firmware run in this mode
● Does not use paging
Life cycle of a system call: sleep
Suppose the following code is executed by a user program test_sleep.c:
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int main()
{
int status = sleep(100);
if (status == -1)
printf("Error\n");
else
printf("Ok\n");
return 0;
}
2. Then we need to define the system call number for getuid in kernel/syscall.h.
// System call numbers
#define SYS_fork 1
...
#define SYS_close 21
#define SYS_getuid 22 // add this line
3. We need to have the definition of int getuid(void) in user/usys.S. This code is
auto generated by user/usys.pl. So, we add an entry for getuid in user/usys.pl.
#!/usr/bin/perl -w
...
entry("uptime");
entry("getuid"); # add this line
4. We need to add a system call handler for getuid. For that we will add a function named
sys_getuid. We need to add a record in the array kernel/syscall.c/syscalls.
So, we make the following changes in kernel/syscall.c.
// Prototypes for the functions that handle system calls.
extern uint64 sys_fork(void);
...
extern uint64 sys_close(void);
extern uint64 sys_getuid(void); // add this line
6. The function sys_getuid calls another function getuid that will be defined in
kernel/proc.c (please note that this getuid function is different from that declared
in user/user.h). Add the following codes at the end of kernel/proc.c. [This step
would not be required if sys_getuid did not call a newly defined function.]
// define a global variable for user id
int uid = 123;
int main()
{
int uid = getuid();
printf("%d\n", uid);
return 0;
}
Practice
Add a system call to set the user id. Also, create a user program to test it.