Sunday, May 31, 2015

System calls

Before starting System call, we will start with OS. Operating System(OS) is a software that manage system resource and provide reliability to users. The Key service provided by OS are,
1. Controlling execution of process
2. Scheduling process in a fairly manner
3. Allocating Main Memory for process
4. Allocating Secondary memory for efficient storage and retrieve data and
5. Allowing process control over peripherals devices.

Application process can't access hardware without the help of Kernel. The below figure shows the privilege levels and communication path.




System call is a primary mechanism for application to interact and request kernel to provide service. So if user want to access system hardware it request system call. When System call get called, it initiate software interrupt/trap. Which makes CPU to switch over from user mode to kernel mode. Interrupt number of software interrupt is 0x80. Below is an example how system call is implemented in assembly language.
/*size_t write(int fd, const void *buf, size_t count)*/

mov edx,count ; message length

mov ecx,buf  ; message to write

mov ebx,fd  ; file descriptor

mov eax,4  ; system call number (sys_write)

int 0x80  ; call kernel

C wrapper function is used, in order to avoid repeated implementation of above code for different system calls. There are lot of pros and cons for using wrapper functions. To add a new system calls you need to build Linux kernel source and then follow the below steps,


1. add entry in "arch/x86/syscalls/syscall_64.tbl". If you are using x86_64 bit system.
# <number> <abi> <name> <entry point>

323    common    test_syscall    sys_test_syscall

2. add "sys_test_syscall()" declaration in "include/linux/syscalls.h"asmlinkage means the function should expect its arguments on the stack rather than in registers.
asmlinkage long sys_test_syscall(void);

3. add definition of "sys_test_syscall()" in a new or existing file.
In our case we added this function in test_syscall.c in directory test_syscall in <kernel_source>
#include <linux/kernel.h>

#include <linux/linkage.h>



asmlinkage long sys_test_syscall(void) {

    pr_err("Successfully created syscall!!\n");

}

4. Make sure the file is build by default. by Adding suitable changes in Makefile
<KERNEL_SOURCE>/test_syscall/Makefile



obj-y    := test_syscall.o



<KERNEL_SOURCE>/Makefile

....

core-y    := usr/ test_syscall/

5. Compile and load the kernel, after compiled kernel get loaded.
Create a c file to call the syscall.
#include <stdio.h>



int main() {

    syscall(323);

    return 0;

}
6. test_syscall kernel print get printed which can be seen in kernel log.
[  2185.076091] Successfully created syscall!!

Here we successfully created the system call. If you need further clarification please comment my blog.


No comments:

Post a Comment