Adding new system-calls Linux kernel 3.5.x

Introduction

System-calls are kernel functions that  serve as an interface (for user mode applications ) to invoke kernel services like drivers, file-systems, Network stacks  and others. system calls are also referred as “kernel entry points” since applications can enter kernel mode only through a valid system call interface. Applications can step into system calls using special processor specific soft interrupt instructions. Linux kernel is widely being deployed and used in virtually every computing platform from desktops, servers, enterprise platforms to Mobile, Deep embedded, Robotics, consumer electronics, medical device platforms  and the list can go on and on.

while customizing and deploying Linux on to various platforms  there may be need for adding new services and system calls to kernel sources.  Fresh programmers to Kernel programming concepts  may find it more interesting to explore system call , API concepts practically by adding new system call, and implementing applications to invoke those calls . (watch linux system calls video tutorial here.) This document provides details of how to add  new system calls to Linux kernel Sources (3.3 version on-words) for x86 32 & 64 bit arch.

Getting kernel sources

we will start by downloading latest stable kernel from kernel community web-site www.kernel.org.  it is a common standard to host source packages in /usr/src branch of rootfs (but you may copy compressed source tar file into any folder).  This document assumes /usr/src/ to be the location of source tar file .

root@techveda:/usr/src# pwd
/usr/src
root@techveda:/usr/src# ls 
linux-3.2.9          linux-3.5.4.tar.bz2     linux-headers-2.6.38-8-generic                             linux-source-2.6.38
linux-3.2.9.tar.bz2  linux-headers-2.6.38-8  linux-image-3.2.9.debug_3.2.9.debug-10.00.Custom_i386.deb  linux-source-2.6.38.tar.bz2
root@techveda:/usr/src#

let’s Extract source from compressed tar file and change our working directory into kernel source tree.

root@techveda:/usr/src# tar xvf linux-3.5.4.tar.bz2 
root@techveda:/usr/src# cd linux-3.5.4
root@techveda:/usr/src/linux-3.5.4# pwd
/usr/src/linux-3.5.4
root@techveda:/usr/src/linux-3.5.4# ls
arch     CREDITS        drivers   include  Kbuild   lib          mm      REPORTING-BUGS  security  usr
block    crypto         firmware  init     Kconfig  MAINTAINERS  net     samples         sound     virt
COPYING  Documentation  fs        ipc      kernel   Makefile     README  scripts         tools
root@techveda:/usr/src/linux-3.5.4#
root@techveda:/usr/src/linux-3.5.4# ls arch/
alpha  avr32     c6x   frv    hexagon  Kconfig  m68k        mips     openrisc  powerpc  score  sparc  um         x86
arm    blackfin  cris  h8300  ia64     m32r     microblaze  mn10300  parisc    s390     sh     tile   unicore32  xtensa
root@techveda:/usr/src/linux-3.5.4#

Above dump shows the contents of arch branch of kernel source.  arch contains Linux hardware abstraction layer code for various architectures that Linux kernel  already includes  support for, kernel maintains an architecture specific system call table  which holds system call addresses.  To add an new system call we need to append a new entry into system call table and store address of syscall function.

syscall table for x86 architecture can be  found in  arch/x86/syscalls branch of kernel source.

root@techveda:/usr/src/linux-3.5.4# ls arch/x86/syscalls/
Makefile  syscall_32.tbl  syscall_64.tbl  syscallhdr.sh  syscalltbl.sh
root@techveda:/usr/src/linux-3.5.4#

syscall_32.tbl  contains system calls for x86 32 bit and syscall_64.tbl   contains intel x86-64bit syscalls. add new entry into appropriate table as per x86 variant you are using .

root@techveda:/usr/src/linux-3.5.4# vim arch/x86/syscalls/syscall_32.tbl 
349     i386    kcmp           sys_kcmp
350     i386    lsproc         sys_lsproc

 New system call is implemented to show list of processes currently load and is given a name lsproc.  we have added a new entry into syscall tableentry  begins with offset no of the table , we added a new offset 350(already table had 249 offsets) , next we mention ABI tag as i386 for 32 bit x86,  next we mentioned name of new system call (lsproc) and at last address of the system call function sys_lsproc (fucntion name resolves to its address).  system call functions in Linux kernel  are assingned names as per  sys_syscallname naming convention, this makes it easy to identify a function as system call  while browsing kernel sources.

User Mode apps will use the offset no of the system call table while invoking system call, in our case the offset application will have to use  350 for invoking lsproc syscall.

X86 64bit

root@techveda:/usr/src/linux-3.5.4# vim arch/x86/syscalls/syscall_64.tbl 
313     64      lsproc                  sys_lsproc

313 is the offset, 64  indicates  x86 64bit  ABI and lsproc is the name of the system call and sys_lsproc is the address of function

Let us now implement our system call function with the name sys_lsproc. we will first declare fucntion prototype in the linux/syscalls.h kernel header

 

root@techveda:/usr/src/linux-3.5.4# vim include/linux/syscalls.h 
asmlinkage int sys_lsproc(void);

asmlinkage  is kernel tag  #defined with a magic  no to instruct compiler   that all arguments to the function must be accessed from kernel stack.  let us implement function code in a new source file lsproc.c . we will host our source file lsproc.c in lsproc directory under kernel branch of source tree.

root@techveda:/usr/src/linux-3.5.4# mkdir kernel/lsproc
root@techveda:/usr/src/linux-3.5.4# vim kernel/lsproc/lsproc.c
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/syscalls.h>

/* system call to print process information
 * prints processname  pid  state
 */
asmlinkage int sys_lsproc(void)
{
        struct task_struct *p;
        pr_info("tProcesstPidtstate");
        for_each_process(p) {
                pr_info("%15st%ut%ld", p->comm, task_pid_nr(p), p->state);
        }
        return 0;
}

we need to add  Makefile and modify kernel build script Kconfig to intergrate our changes into source tree.

root@techveda:/usr/src/linux-3.5.4# vim kernel/lspoc/Makefile 
obj-$(CONFIG_LSPROC) += lsproc.o

 

root@techveda:/usr/src/linux-3.5.4# vim kernel/Kconfig.lsproc
config LSPROC
  bool "list current processes"
  default y
  help
    This will list all current running process pid and their state

This completes the process of integrating new system call into kernel source tree.  Now Its time to compile kernel sources  and create a new kernel image that includes our system call. Following make commands will compile, build and install the new kernel image.

 

root@techveda:/usr/src/linux-3.5.4# vim Makefile 
EXTRAVERSION =.syscall
root@techveda:/usr/src/linux-3.5.4#make menuconfig
root@techveda:/usr/src/linux-3.5.4#make
root@techveda:/usr/src/linux-3.5.4#make modules_install 
root@techveda:/usr/src/linux-3.5.4#make install

look here for more details on kernel build

 Test Application

Application can invoke the system call using x86-32bit  trap exception  with system call offset as a parameter passed into eax accumulator register.

root@techveda:~# vim lsproc.c

#include <stdio.h>
#include <stdlib.h>

int lsproc()
{
        int ret;
        __asm__("movl $350, %eax");
        __asm__("int $0x80");
        __asm__("movl %eax, -4(%ebp)");
        return ret;
}

int main()
{
        int ret;
        printf("invoking system calln");
        ret = lsproc();
        if (ret < 0)
                exit(1);
        return 0;
}
root@techveda:~# gcc lsproc.c -o lsproc
root@techveda:~# ./lsproc 
invoking system call
root@techveda:~# dmesg

Dmesg would list process list extracted and printed by our system call on console.

 

 

Tags: , , , , , , , , ,

32 Responses to “Adding new system-calls Linux kernel 3.5.x”

  1. arungopal says:

    how to create a root file system for arm board and how to build a kernel for for arm board and how to create a zimage for arm board…Please post this procedure….

    Current score: 0
  2. Sandeep K Rai says:

    The best way of build the kernel and Install in Ubuntu is: Take your kernel 3.5.x/ + version and make the changes in their source tree accordingly this tutorial, and do folloing steps
    1- make menuconfig -> if any package is missed in your ubuntu then install, missed package will be mentioned while you use this command , then install it as you do in ubuntu.
    2- make bzImage ->do it and open another terminal go in same path and do 3rd stage
    3- make modules
    when 2, 3 rae completed then do steps 4 in any terminal but in same path…
    4- make modules_install
    5- make install
    Restart your PC and select new installed kernel to boot. then after write the user space program and run it as you run simple c program in linux……
    All the Best!!!!!!!!!

    Current score: 0
  3. Karthigan says:

    In other words, how do I make a call to my system call without the assembly language code in the userspace? I would like to just be able call lsproc just like would to the system calls sleep, getpid etc.

    Current score: 0
  4. Magesh says:

    Please let me know how to access the system call from user program the normal way without using the trap instruction in the user program. I had tried many things like installing the kernel headers using make install, but nothing seems to work. The required header file changes doesnt seem to be generated at all during the kernel compilation.

    Current score: 0
  5. techveda says:

    look here for installation commands
    http://blog.techveda.org/index.php/ubuntu-essential-add-ons-for-programmers/

    Current score: 0
  6. saikrishna says:

    sir, when i give make menuconfig, it asks to install ncurses. How do i do that?

    Current score: 0
  7. techveda says:

    follow these steps for kernel build

    1. make menuconfig
    2. make
    3. make modules_install
    4 make install

    Current score: 0
  8. techveda says:

    follow these steps for kernel build after adding system call

    1. make menuconfig
    2. make
    3. make moudles_install
    4. make install

    Current score: 0
  9. techveda says:

    after assigning build name , you must begin with make menuconfig

    Current score: 0
  10. Pradeep G says:

    am strucked with an error ,i have fallowed the same steps as mentioned but
    arch/x86/built-in.o:(.rodata+0x1474): undefined reference to `sys_prints’
    make: *** [.tmp_vmlinux1] Error 1
    i don’t undastand where i did the mistake where sys_prints is my system call where i wrote nothing other than a printk statemenet in the defination of function.
    for kernel -3.4.2

    Current score: 0
  11. Pradeep G says:

    sir,after adding Extra version .syscall
    do i need to go for menuconfig or make BZimage..?
    if i go it is asking for updation of config

    Current score: 0
  12. Madhava says:

    I recieved an error in built-in.o(.rodata+1832e):undefined reference to ‘sys_lsproc’.please help..

    Current score: 0
  13. Anali says:

    thank you very much…this helps 🙂

    Current score: 0
  14. techveda says:

    try following steps

    1. Add sys call id
    ($kernel_source)/arch/x86/include/asm/unistd_32.h
    2. append syscall address to syscall switch table
    ($kernel_source)/arch/x86/kernel/syscall_table_32.S
    3. declare function prototype
    ($kernel_source)/include/linux/syscalls.h
    4. implement syscall routine and modify Kconfig and Makefile as described in the article above

    Current score: 0
  15. Anali says:

    so does this mean that we can not add system calls to kernels below 3.3 ?

    Current score: 0
  16. techveda says:

    check kernel version,you must find syscalls under /arch/x86 in kernel versions 3.3.x and above

    Current score: 0
  17. Anali says:

    Thank you very much for the detailed explanation, however I cannot find the syscalls folder under /arch/x86…any ideas what is wrong?
    Thank You !

    Current score: 0
  18. Suku says:

    simply superb sir……

    Current score: 0
  19. dhananjaya says:

    excellent sir………………

    Current score: 0
  20. vasubabu says:

    now i know why raghu sir is so good…

    Current score: 0
  21. naveen says:

    thanks for sharing the knowledge

    Current score: 0
  22. Chiranjeevi says:

    nice work

    Current score: 0
  23. Neelima says:

    Nice one. Thanks.

    Current score: 0
  24. suman says:

    Wow Thank you very much for the information . Thank you Raghu sir and sathish who helped me alot to get the job

    Current score: 0
  25. Praveen says:

    useful info … thanq

    Current score: 0
  26. Praveen says:

    useful info … thankq

    Current score: 0
  27. sravan says:

    good one

    Current score: 0
  28. Arnav says:

    Was looking for this , thanks

    Current score: 0
  29. sr vani says:

    Thanks a ton

    Current score: 0
  30. Sekar says:

    Spot on, good jobs

    Current score: 0

Leave a Reply