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 2.6.35.7 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 2.6.35.7 would work fine )and untar it to get linux-2.6.35.7. The paths used below all will be relative to this path.
We need to edit 4 files and 2 files need to be created.
The Code
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.
obj-y:=strcpy.o
Thus, now the strcpy.c file and Makefile are present in
linux-2.6.35.7/test/strcpy.c
linux-2.6.35.7/test/Makefile
The Edits
The following files need to be edited.
1. linux-2.6.35.7/arch/x86/kernel/syscall_table_32.S
Append to the file the following line
.long sys_strcpy
2. linux-2.6.35.7/arch/x86/include/asm/unistd_32.h
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.
3. linux-2.6.35.7/include/linux/syscalls.h
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);
4. Makefile
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
make install
Once the kernel image is installed to /boot, reboot the system.
Testing
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
Note:
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.
#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 id #define NR_syscalls 339 Note down the number 338, we need it later. 3. /usr/src/linux-2.6.32.5/include/linux/syscalls.h This file contains the prototypes of system calls. Here we append to the file the prototype of our file.
ie. We add the line
asmlinkage long sys_strcpy(char *dest,char *src); 4. Makefile
Open makefile and find the area where core-y is defined and add the folder test to the end of that line as shown below






Alan said
kewll one dude…u are gifted bro… waitin for ur new projects n articles…
Implementing a System call in Linux Kernel 2.6.35 « [ Curiosity … | Linux Affinity said
[...] here to see the original: Implementing a System call in Linux Kernel 2.6.35 « [ Curiosity … Posted in: Kernels ADD [...]
Nikhil George said
Good work
Primal said
Nicely done.
Jain Basil Aliyas said
Really informative post.
vidya said
As every body say u ve done a great job as usual,
neat diagrams, good language..
waiting to see more from you dear..
really informative..
raji said
i am doing mini project adding a new system call in linux kernel.your example was helpful and superb.but i dont know how can i open and edit that file linux-2.6.35.7/arch/x86/kernel/syscall_table_32.S.please help me………..
appusajeev said
download linux kernel from http://www.kernel.org/ , unzip the contents, u will get a folder like linux-2.6.xx.x , inside that folder, you can see ‘arch’ folder , and inside it ‘x86′, inside it ‘kernel’ and inside it, you can see the file ‘syscall_table_32.S’. Make changes to this file as specified in the post
hcimusings said
Hi Appu,
I am trying to implement a system call in my 2.6.35.11 kernel (fedora running on vmware). I was using this tutorial :http://hekimian-williams.com/?p=20
Well i had some doubts:
i)I cannot find /incude/asm instead i have asm-generic which also has unistd.h.
ii)When I compile the kernel using “rpmbuild –bb –with baseonly –with firmware –without debuginfo \ –target=i686 kernel.spec” ,
all my Makefile, and .c files (for system call, the whole folder is getting deleted), I guess there are some update patches that are deleting all my code, is there any way to compile the kernel with upate patches disabled?
appusajeev said
Hello Anand
The kernel source i used was downloaded from kernel.org, and i was using make to compile the kernel after proper configuration and it compiled just fine, no files were modified or deleted. I suggest you try this method. I havent yet used rpmbuild method, so i am not sure if i can help you in this matter. Just compile a freshly downloaded kernel in the traditional way. It should work fine.
anand said
how to prevent….an rpmbuild from rewriting all the source code changes, by applying all the update patches?
thnaks!
appusajeev said
Please see my reply to your earlier question..
Jinesh said
I done the same things on my kernel. But when I compile I got this error
“:1523: warning: #warning syscall strcpy not implemented”
and new system call not working recompiled kernel
appusajeev said
Please provide more details about the error. Post the code that caused the error…
Jinesh said
I solved by adding this line
#define __NR_strcpy 303
__SYSCALL(__NR_strcpy, sys_strcpy)
to arch/x86/include/asm/unistd_64.h
Thanks for reply
Ben said
Thank you–this is amazing! I spent hours trying to find the right source file to modify before coming across this!
appusajeev said
glad that was of help
yuft said
Appusjeev can you please explain me how to update the dev variable
appusajeev said
what do you mean update the dev variable?
james said
really appreciate the post had to add some system calls to the kernel for an OS project and the TA had no idea what was going on everyone is completely rebuilding the entire kernel not using bzimage you saved me a ton of time again thanks. Would it be possible to get a tutorial on creating/accessing structs within the kernel space?