[ Curiosity,Experimentation ]

Some random stuff from the world of Programming

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.

Code for the system call

Code for the system call

<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

linux-2.6.35/arch/x86/kernel/syscall_table_32.S

linux-2.6.35/arch/x86/kernel/syscall_table_32.S

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.

linux-2.6.35/arch/x86/include/asm/unistd_32.h

linux-2.6.35/arch/x86/include/asm/unistd_32.h

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);


linux-2.6.35/include/linux/syscalls.h

linux-2.6.35/include/linux/syscalls.h

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

Makefile

Makefile

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 :)

System call test

System call test

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.

<1> means that we are giving that message the highest priority Create a folder name ‘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 the line Obj-y:=strcpy.o The Edits The files to be edited are 1 . /usr/src/linux-2.6.32.5/arch/x86/kernel/syscall_table_32.S Append the line  .long sys_strcpy to the file(Replace sys_strcpy with whatever name you want) 2. /usr/src/linux-2.6.32.5/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 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
About these ads

26 Responses to “Implementing a System call in Linux Kernel 2.6.35”

  1. Alan said

    kewll one dude…u are gifted bro… waitin for ur new projects n articles…

  2. [...] here to see the original: Implementing a System call in Linux Kernel 2.6.35 « [ Curiosity … Posted in: Kernels ADD [...]

  3. Nikhil George said

    Good work

  4. Primal said

    Nicely done.

  5. Really informative post.

  6. 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.. :)

  7. 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.

  8. anand said

    how to prevent….an rpmbuild from rewriting all the source code changes, by applying all the update patches?

    thnaks! :)

  9. 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

  10. Ben said

    Thank you–this is amazing! I spent hours trying to find the right source file to modify before coming across this!

  11. yuft said

    Appusjeev can you please explain me how to update the dev variable

  12. 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?

  13. Useful dude. nice presentation.

  14. Awh said

    How to TEST the system call? Teach me please I don’t know what to do in the TESTING part! Thanks

    P.S. Newbie here :))

  15. Ansjj said

    If i directly start compiling kernel using make bzImage , it says that you have not yet configured your kernel, use some configerator e.g. make menuconfig.
    when i use ‘make menuconfig’ it says that unable to find uncurses libraries or header files. ‘make menuconfig’ requires ncurses libraries. Install ncurses(ncurses-devel) and try again.

    What should i do..? please help!

  16. gunjan deotale said

    cool dude!! keep it up

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

Join 29 other followers

%d bloggers like this: