Upcoming Posts

Upcoming Posts....

Make your own partition magic software.
How to make an assembler.
What is booting?
Write a simple OS!

‎"I have no special talents. I am only passionately curious." - Albert Einstein

Wednesday, April 18, 2012

Invoking System calls on Linux

It is not possible to directly link (using any compiler) user-space applications with kernel space. For security and reliability reasons, the user-space applications must not be allowed to directly execute kernel code or manipulate kernel data. Instead, the kernel must provide a mechanism by which a user-space application can "signal" the kernel that it wishes to invoke a system call. The application can then trap into the kernel through this well-defined mechanism, and execute only code that the kernel allows it to execute. The exact mechanism varies from architecture to architecture.
According to x86-32 Linux System Call convention (on the i386 architecture), Linux System-call is done via "int 0x80" instruction and the following registers are used to pass parameters to kernel:
eax -  System call number.bx, ecx, edx, esi, edi, ebp - Used for passing 6 parameters.If there are more than six arguments, ebx must contain the memory location where the list of arguments is stored. Return Values depends on system calls. Most system calls uses EAX to return values, but not for all. If it is not there, you need further research :).
According to x86-64 Linux System Call convention, Linux System-call is done via the "syscall" instruction and the following registers used to pass parameters to kernel:
eax -  System call number.rdi, rsi, rdx, r10, r8 and r9. - Used for passing 6 parameters.
Please note that the kernel destroys registers rcx and r11. Thus you may need ot take care of the values stored rcx and r11.
Return Values depends on system calls. Most system calls uses EAX to return values, but not for all. If it is not there, you need further research :).
There are three ways to invoke System call:
1. Invoking System Calls indirectly by calling C/C++ standard methods:
exit_c.c:
void main()
{
exit(6); /* to exit current process with 6 as exit code */
}
gcc exit_c.c
./a.out
Here, we are calling C/C++ "exit()" method to terminate process with 6 as exit code. This "exit()" method present in C/C++ library will make appropriate system call to terminate the process. Since we are calling standard method here. This program will be portable and can work on all the platforms.
2. Invoking System Calls indirectly by calling C wrapper methods for system calls:
exit_ind_sys.c:
void main()
{
syscall(1,6); /* 1 is System call number for exiting program and 6 is the user defined exit status code */
}
gcc exit_ind_sys.c
./a.out
Here, "syscall()" is a GNU C library function. It is harder to use and less portable than C functions like "exit()", but easier and more portable than coding the system call in assembler instructions.
3. Invoking System Calls directly by writting assembly code:
exit_as.c:
void main()
{
asm(
"movl $1, %eax\n\t" /* 1 is System call number for exiting program */
"movl $6, %ebx\n\t" /* 6 is the user defined exit status code */
"int $0x80\n\t"     /* */
);
}
gcc exit_as.c
./a.out
Here, we are calling System API directly by executing "int $0x80" instruction from program itself. This makes it non-portable code. It will work with Linux on Intel machines only.
Getting System call numbers and their parameters:
System call numbers are defined in "/usr/include/asm/unistd.h" header file as "#define _NR_exit 1". Parameters to each system call is defined in "syscalls.h" file as "asmlinkage long sys_exit(int error_code);".
[root@localhost linux]# find / -name syscalls.h/usr/src/kernels/2.6.18-8.el5-i686/include/linux/syscalls.h


Linux Header Files:



/usr/include/asm/*.h
The Linux API ASM Headers
/usr/include/asm-generic/*.h
The Linux API ASM Generic Headers
/usr/include/drm/*.h
The Linux API DRM Headers
/usr/include/linux/*.h
The Linux API Linux Headers
/usr/include/mtd/*.h
The Linux API MTD Headers
/usr/include/rdma/*.h
The Linux API RDMA Headers
/usr/include/scsi/*.h
The Linux API SCSI Headers
/usr/include/sound/*.h
The Linux API Sound Headers
/usr/include/video/*.h
The Linux API Video Headers
/usr/include/xen/*.h
The Linux API Xen Headers
                   



Reference:
http://stackoverflow.com/questions/2535989/what-are-the-calling-conventions-for-unix-linux-system-calls-on-x86-64
http://asm.sourceforge.net/syscall.html

No comments:

Post a Comment