Implementing a System call in Linux Kernel 2.6.35
Posted by appusajeev on November 13, 2010
As we know, System calls are a set of services/functions provided to the programmer by the OS. These functions can be invoked in any language that provide some interface to the System call mechanism of the OS. Some common linux system calls are open,read,write etc.
While executing a system call, the calling process moves from user space to kernel space and back to user space when its completes executing the call.
There are around 338 system calls in linux kernel 18.104.22.168 by default. Presented here a howto on adding a new one into the kernel, a 339th one so that it will be available globally for any program. As example, we will implement the strcpy function as a system call so that it can be used without including string.h.
Obviously, you need the kernel source tree since some kernel modification is involved. Get it from kernel.org (any kernel version higher than 22.214.171.124 would work fine )and untar it to get linux-126.96.36.199. The paths used below all will be relative to this path.
We need to edit 4 files and 2 files need to be created.
First, lets start off writing the code for strcpy. We need to include the file linux/linkage.h because it contains the macro asmlinkage which means that the system call expects the arguments on the stack and not in registers. Printk is the kernel alternative of printf, but with certain peculiar properties.
“<1>” tells printk that we are giving that message the highest priority.
Create a folder named ‘test’ in the root of linux source directory and save this file as strcpy.c in that directory. Create a Makefile in that directory containing only the line.
Thus, now the strcpy.c file and Makefile are present in
The following files need to be edited.
Append to the file the following line
This file contains the unique number associated with each system call. We can see the names of all the system calls and the number associated with each. After the last system call-number pair (around line 345), add a line
#define __NR_strcpy 338
(if 337 was the number associated with the last system call).
Then replace NR_syscalls directive denoting the total number of system calls by the previous number incremented by 1 ie the new value is
#define NR_syscalls 339
Note down the number 338, we need it later.
This file contains the prototype of all the system calls. Here we append to the file the prototype of our function.
ie. We add the line
asmlinkage long sys_strcpy(char *dest,char *src);
Open Makefile present in the root of source directory and find the area where core-y is defined and add the folder test to the end of that line as shown below
Next compile the kernel. Assuming you are familiar with kernel compilation, execute
make bzImage –j4
The last argument is optional and is intended to speed up compilation on dual core CPUS
Once compilation is complete, install the kernel by executing the following command with root permission
Once the kernel image is installed to /boot, reboot the system.
Now we need to check the newly done system call. Run the code below and feel the satisfaction :)
The kernel has performed the strcpy for us. Cool ! isn’t it
Execute the command dmesg now, you can see done printed in the last. Printk by default doesnt print to the terminal. It writes to the kernel ring buffer which is printed by the dmesg
Try putting an infinite loop inside a system call, the system just drops dead. As it goes, the linux kernel does not preempt itself.