Adding A System Call To Linux (Fedora 9)

By Cory Hekimian-Williams on Nov.08, 2008, under Linux, Programming

Getting Started

The procedure to create a system call varies in different versions of Linux. I will provide a simple step by step guide on adding a system call to the Fedora 9 kernel. The version I used to write this document was Fedora 9 kernel 2.6.26 (i686). I originally wrote this while I was a TA for an undergraduate Operating Systems course at FSU.

When you add a system call you will have to recompile the Linux kernel, so you must have the Linux source tree installed on your system. Furthermore, compiling the kernel can take a good amount of time (depending on the system and kernel options to it can take hours), so give yourself time. There is a way to add system calls without recompiling the kernel using modules as a wrapper, but that is beyond the scope of this document.

Notes

When folders are described with source/ at the start of the path, it represents the highest level of the Linux source tree. You should have folders such as arch, configs, include, and init in this folder.

Creating the System Call Source

We will be creating a simple hello world system call. Create a file mysyscall.c and fill it with the following code.

#include <linux/kernel.h>
#include <linux/linkage.h>

asmlinkage long mysyscall(int i){
    printk(KERN_DEBUG "Hello World! The number was %dn", i);
    return(1);
}

Adding the System Call

1. Firstly, navigate to the root directory of your Linux source. Create a folder source/mysyscall. Next, inside of your newly created folder, add a source file mysyscall.c that contains all of your system call source code.

2. Next, create a make file within this directory. This make file only needs to contain one line that says what to compile.

Create source/mysyscall/Makefile (keep the capital ‘M’)

obj-y := mysyscall.o

3. Next we need to modify the kernel’s make file. This is located in the root folder of your kernel’s source. Find the line that adds a bunch of folders to the core-y variable and add the folder name that the system call source is in. (mysyscall in this example)

In source/Makefile, the line to change looks something like this:

core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/

It should be changed to something like this:

core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ mysyscall/

4. Now, navigate to the source/arch/x86/kernel folder. You will need to add your system call to the system call table. This is done in the file syscall_table_32.S. At the end of the file you add an entry for the new system call. Make sure to prefix your entry with “sys_”.

It should look something like this:

.long sys_mysyscall

You should notice the numbers commented out to the right of some of the entries. They tell you what number the system call is. Keep track of which number your new system call is.

5. Next navigate to the source/include/asm-x86 folder and edit unistd_32.h. Add a #define line for the new system call. Use the number that you noted in the last step.

You should add a line similar to this:

#define __NR_mysyscall 327

6. You are now ready to recompile your kernel.

Using the System Call

1. Next to use the system call we need to create a header file that exposes the new call. Create a file, mysyscall.h which will be imported into any program that wants to use the new system call.

This header file should contain the following:

#include "unistd.h"
#define __NR_mysyscall 327

long mysyscall(int i){
    return syscall(__NR_mysyscall, i);
}

2. Write a program that includes your newly created header file, and then call the mysyscall (int i) function you have implemented.

Adding a Variable Shared Between a System Call and a Kernel Module

1. Using External Variables

In order to use a variable that has been declared in another file, the keyword extern must be used.

#include <linux/kernel.h>
extern int myVar;

int MyModuleFunction(){
    /* Has access to myVar which is defined in a different kernel file*/
}

2. Making Variables Externally Visible

However, variables are not visible to other files by default. For a variable declared in a system call to be visible to a kernel module it must be exported. To export a variable you must use the macro EXPORT_SYMBOL. You can export functions as well using this same macro.

#include <linux/kernel.h>

int myVar;
EXPORT_SYMBOL(myVar);

static int MySystemCall(){
    /* Has access to myVar */
}

Adding a system call to Linux can sometimes be a daunting task, especially the first time. I hope this document was helpful.

:, ,

17 Comments for this entry

  • mike

    hey thanks for the tutorial, it helped to guide me through add a syscall on fedora 11 (i think) too.

    One thing to note the mysyscall function needs to return a long in order for it to work properly.

    so maybe something like this:

    asmlinkage long mysyscall(int i){
    printk(KERN_DEBUG “Hello World! The number was %dn”, i);

    return 123213;
    }

  • Cory Hekimian-Williams

    Glad it was helpful, thanks for the correction, I fixed the function.

  • shubha

    I am using linux-2.6.28.10 (Ubuntu jaunty). I am unable to locate the include/asm-x86 folder. Should i copy-paste it ? Adding a system call to i386 architecture seems to be easier but i am not sure it would work on i686 machines. Please help.

  • shanim

    Hi, tutorial is really helpful, one change in mysyscall.c as
    asmlinkage long mysyscall(int i){
    asmlinkage long sys_mysyscall(int i){

    Thanks

  • Rahul

    I cant find entry.S file while trying to add system call..
    Please suggest a way out…This is my undergraduate project

  • Ernestina Magness

    Awesome blog post. I have got to say though that for operating systems, I am still old school and usually go with ones that have had the bugs ironed out for a couple years, how about you?

  • teja

    can u upload a video of this entire process?

  • aliftek

    Hi,I have done but when i have compiled i m getting “unreference mysyscall”.plz help me?thnx

  • komal patel

    hi…
    I have used this procedure but do not able to add the systemcall plz help me soon

  • rahul

    I have used each step carefully but the make process i get a error saying
    in table Syscalltable_32.S
    undefined reference to mysyscall please help. soon..

  • Renate Walking

    hello all, I was just checkin’ out this site and I really admire the basis of the article, and have nothing to do, so if anyone would like to to have an enjoyable conversation about it, please contact me on squidoo, my name is michael pollum

  • Mirrored Furniture %0B

    ~’” I am really thankful to this topic because it really gives useful information .~.

  • linux commands

    I like the valuable info you provide in your articles. I’ll bookmark your blog and check again here regularly. I’m quite certain I will learn lots of new stuff right here! Good luck for the next!

  • m.k.

    Hello
    Thanks
    I have a question about your sentence : “There is a way to add system calls without recompiling the kernel using modules as a wrapper, but that is beyond the scope of this document.”

    How can we do it? Can you say me the way or get me some link to other references?

    Thanks

  • linux download

    Very good blog. I reali like it! Good 4 you;)

  • Linux

    Nice blog & interesting post!

  • TheFu

    Thanks for posting, very good website

The following websites reference this page.

Leave a Reply

Links!