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 table, entry 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: asmlinkage, how to add new system calls, int $0x80, kernel build, kernel compilation, kernel source, make bzImage, make modules, system-calls, sys_syscall

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….
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!!!!!!!!!
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.
http://blog.techveda.org/index.php/linux-system-calls-video-tutorial/
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.
look here for installation commands
http://blog.techveda.org/index.php/ubuntu-essential-add-ons-for-programmers/
look here
http://blog.techveda.org/index.php/ubuntu-essential-add-ons-for-programmers/
sir, when i give make menuconfig, it asks to install ncurses. How do i do that?
follow these steps for kernel build
1. make menuconfig
2. make
3. make modules_install
4 make install
follow these steps for kernel build after adding system call
1. make menuconfig
2. make
3. make moudles_install
4. make install
after assigning build name , you must begin with make menuconfig
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
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
I recieved an error in built-in.o(.rodata+1832e):undefined reference to ‘sys_lsproc’.please help..
thank you very much…this helps 🙂
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
so does this mean that we can not add system calls to kernels below 3.3 ?
check kernel version,you must find syscalls under /arch/x86 in kernel versions 3.3.x and above
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 !
simply superb sir……
excellent sir………………
now i know why raghu sir is so good…
thanks for sharing the knowledge
nice work
Nice one. Thanks.
Wow Thank you very much for the information . Thank you Raghu sir and sathish who helped me alot to get the job
useful info … thanq
useful info … thankq
good one
Was looking for this , thanks
Thanks a ton
Spot on, good jobs