Thursday 20 December 2012

System Calls Implementaion in Linux (for both older and newer version) in x86

Implementation of System Call in Older Linux Version


Step 1:
Reserve a system call number
path: (inside linux source tree) /arch/x86/include/asm/unistd_32.h
Go to the end and add the system call number and also modify NR_syscalls by adding 1.
e.g. : #define __NR_my_add     350
Step 2:
Declare system call prototype
path: /arch/x86/include/asm/syscalls.h
go to : #ifdef CONFIG_x86_32 (for 32 bit) or common (for both 32 or 64 or ..._64
asmlinkage long sys_my_add(int,int);
Step 3:
Append system call address to sys_call_table
path: /arch/x86/kernel/syscall_table_32.S
Go to the last position, here I'm going to the 350th position (same position as call number) and write
.long sys_my_add
Step 4:
Implement syscall Routine
It can be done in one of the two ways:
i. Add the function to the existing source file ( you don't have to change the source file)
ii. Adding a source file ( however, modify the Makefile to compile this file too)
e.g.:
asmlinkage long sys_my_add(int a,int b)
{
        printk(KERN_ALERT "The sum is %d ",a+b);
        return a+b;
}
Now, This function can be added to any existing file. If so we are done but if we have created a file say my_add.c then don't forget to add following line in a Makefile where this code exist.
obj-y := my_add.o


Implementation of System Call in Newer Linux Version


Step 1:
Now, if you would follow the previous method you would be surprise to find that
/arch/x86/include/asm/unistd_32.h file doesn't exist. It does however exist but has been removed from there and is saved in generated directory which gets generated automatically. Rather now we have to follow to the following path to modify the system call table.
path: /arch/x86/sycalls/sycall_32.tbl
Now, the table is of the form as below:
<number> <api> <name> <entry point><compat entry point>
number: specify the system call number ie increase the count of the last system call by 1
api : in the case of x86 it is by default i386
name: name of the system call
entry point: it is the entry point for our system call
compat entry point: if our call has a compat entry point
eg:
350   i386   my_add    sys_my_add
After doing this automatically the system call number gets appended in unistd_32.h and we don't have to do anything.

Step 2:
Follow the step 2 of older version.

Step 3:
Follow the step 4 of older version.


Calling the system call from user space after building the kernel


#include<stdio.h>
#include<unistd.h>
int main()
{
        int a,b,c;
        a=35;
        b=45;
        c=sycall(350,a,b);
        printf("\nThe value of the sum is %d \n",c);
        return 0;
}

No comments :

Post a Comment