Monday, 28 November 2011

System Call In Linux

                                                          System calls provide a layer in between the hardware and the application programs. The system calls server for 3 primary purposes.
1. it provides a abstracted hardware interface to the user process.
2. it provides the system security and stability.
3. it provides a virtualized system to process.
The system calls are the only legal entry point to the kernel other than exceptions and traps.

Api and System call.

                                   When an application programmer calls a printf or some other api the corresponding funtion in the c library will be invoked and that in turn will call some system call which is implimented in the c library and which in turn will call the kernel's system call using the system call number. Syscalls are often accessed by the function calls defined in the c library . They can be called with zero one or more arguments , and might result in one or more side effects. System call provides a return value of long. The return value will indicate a success or failure of the system call. Usually zero is a success. and negative value is an error . When an error occurs a global errorno variable is set to a error code and it can be transformed to a user readable format by using perror function.
A system call definition looks like this.
asmlinkage long sys_mysyscall(void)

The asmlinkage directive tells the compiler to look only on the stack for that function's arguments.
mysyscall is defined as sys_mysyscall this is the naming convention .

system call read is implemented in kernel as sys_read.

System call number.
In linux each system call has a unique number. When a user space process  executes a system call, the system call number identifies which system call was executed. The process does not refer to the system call by name. Kernel keeps track of all registered system calls in a system call table. In my system it is in the file arch/x86/kernel/syscall_table_32.S 

System call handler.
It is not possible for a user space process to execute a kernel space code by calling a function because kernel resides in a special memory protected area . If an application program were allowed to write, to read or call a kernel space method or function it would become a security loophole . So what user process does is that they signal the kernel saying that they need to execute a system call, kernel on getting this signal will execute the system call on behalf of the user space application . The mechanism to do this signaling is called the software interrupts . It is somewhat like an exception when user signals a software interrupt the process will be switched to kernel mode and the corresponding exception handler will be executed. In this case it is called as a system call handler. In x86 architecture the sotware interrupt has the number 0x80 and it can be triggered using the instruction int $0x80. The system called handler is a named function called system_call(). its implementation can be found in arch/x86/kernel/entry_32.S 
After entering to the kernel space  there are so many system calls the user will have to pass the system call number to the kernel before the software interrupt is executed. this is done by in x86 by filling eax register with the system call number and then calling int 0x80 ;if the system call number is a valid number the the system_call execute the corresponding systemcall by doing 
call *sys_call_table(,%rax,4)
each element in the system call table is 4 byte in a 32 bit processor so the the kernel multiplies the given value with four to arrive at correct location in the system call table.

                              The parameters to the system call are passed to the kernel before the software interrupt by filling them in the registers 
if more than 5 arguments are needed to then we use a single register to fill the pointer to user space where all the parameters are stored. The return value is also send to user space via register eax.

Step 1:
create a folder in the root of your kernel source tree and go to that directory.

step 2:
write your system call in a file like mycall.c



asmlinkage long sys_myscall(void)


    printk(<1>"Hell, world\n");

    return 0;


step 3:
Create a Makefile which contains ,
obj-y := myscall.o

step 4:
add a line like given below to the file  arch/x86/kernel/syscall_table_32.h .
.long sys_myscall

step 5:
add a line like given below to the file arch/x86/include/asm/unistd_32.h
#define __NR_myscall
and also change the NR_syscalls to the previous number + 1

step 6:
add a line like given below to the file include/linux/syscalls.h
asmlinkage long sys_myscall(void);

step 7:
add your system call files folder i.e, test to the core-y variable in Makefile

step 8: 
compile the kernel.

Testing your system call 

1 comment:

  1. could you please tell me how to compile the kernel and test the system call.