+

What is a system call?

+

As you all know, an operating system supports two modes; the kernel mode and the user mode. + When a program in user mode requires access to RAM or a hardware resource, it must ask the kernel to + provide access to that particular resource. This is done via a system call. When a program makes a + system call, the mode is switched from user mode to kernel mode. + There are many system calls in an operating system which executes different types of tasks when they + are called. +

+ +

Adding a custom system call in xv6

+

In order to define your own system call in xv6, you need to make changes to 5 files. Namely, these + files are as follows.

+
+
+
+                            
+                                1. syscall.h
+ 2. syscall.c
+ 3. sysproc.c
+ 4. usys.S
+ 5. user.h +
+
+
+
+

Let’s write a system call to return the year Unix version 6 was released.

+

We would start the procedure by editing syscall.h in which a number is given to every system call. + This file already contains 21 system calls. In order to add the custom system call, the following + line needs to be added to this file.

+
+
+
+                            
+                                #define SYS_getyear 22
+                            
+                        
+
+
+

+ Next, we need to add a pointer to the system call in the syscall.c file. This file contains an array + of function pointers which uses the above-defined numbers (indexes) as pointers to system calls + which are defined in a different location. In order to add our custom system call, add the following + line to this file. +

+
+
+
+                            
+                                [SYS_getyear] sys_getyear,
+                            
+                        
+
+
+ +

+ What exactly happens in here? +

+

The underlying meaning of the above two changes is as follows.

+
    +
  • + When the system call with number 22 is called by a user program, the function pointer + sys_getyear which has the index SYS_getyear or 22 will call the system call function +

    +
  • +
+

+ Therefore, we need to implement the system call function. However, we do not implement the system + call function in the syscall.c file. Instead, we only add the function prototype in here and we + define the function implementation in a different file. The function prototype which needs to be + added to the syscall.c file is as follows. +

+
+
+
+                            
+                                extern int sys_getyear(void);
+                            
+                        
+
+
+

+ Next, we will implement the system call function. In order to do this, open the sysproc.c file where + system call functions are defined. +

+
+
+
+                            
+                                // return the year of which the Unix version 6 was released
+ int
+ sys_getyear(void)
+ {
+ return 1975;
+ }
+
+
+
+
+

+ The basic implementation of the system call is now complete. However, there are 2 more minor steps + remaining. +

+ +

Add the interface for the system call

+

In order for a user program to call the system call, an interface needs to be added. Therefore, we + need to edit the usys.S file where we should add the following line. +

+
+
+
+                            
+                                SYSCALL(getyear)
+                            
+                        
+
+
+

Next, the user.h file needs to be edited. +

+
+
+
+                            
+                                int getyear(void);
+                            
+                        
+
+
+

+ This would be the function which the user program calls. This function will be mapped to the system + call with the number 22 which is defined as SYS_getyear preprocessor directive. +

+

+ If you have completed all of the above, you have successfully added a new system call to xv6. + However, in order to test the functionality of this, you would need to add a user program which + calls this system call. +

+

+ The user program could be as follows. +

+
+
+
+                            
+                                #include “types.h”
+ #include “stat.h”
+ #include “user.h”
+
+ int
+ main(void)
+ {
+ printf(1, “Unix V6 was released in the year %d\n”, getyear());
+ exit();
+ }
+
+
+
+
+