What Are System Calls

You might also like

Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 12

What are system calls

 
System calls are a way for User land process to interact and get
data from kernel. System call helps in controlled and well defined
access to linux kernel through standard set of API's.

Since linux kernel and user process runs in different ring level and
have different access to virtual memory so it becomes pertinent to
have a way to access kernel resource from user level and system
call helps in doing exactly the same.
 There has been a continuous change to linux kernel in terms of how system
calls are implemented and used. Our example code and program is tested for
linux kernel 3.9.4, you can try on other version of kernel(Not very old but
probably 3.5 onwards) but it has not been tested.
 The test system which we have used for this purpose is i386 machine
Running Ubuntu linux 12.10.
 Since implementing a system call needs to compile and load a new kernel as
well as modification of system header file for new calls to be added, this
may render your system useless in case of not following the instructions
perfectly or may be due to reason beyond our control. User is advised to
keep the backup of the files they are modifying and we owe no
responsibility what so ever for any type of loss.

 glibc provides a wrapper for most of the system call provided by linux
kernel except for few like gettid which fetches the caller thread ID
System call are a means to switch from User mode to kernel mode and Vice-
versa.
Linux maintains a list of system call in a table with the number, this is
present in file
arch/x86/syscalls/syscall_32.tbl for 32 bit architecture and
arch/x86/syscalls/syscall_64.tbl for 64 bit architecture.
 
Long before the advent of special instruction set for x86 architecture like
sysenter and sysexit, the linux kernel provides software interrupts 0x80 to
enter the kernel mode or ring 0 from ring 3 which is user space(ring 1 and 2
and not used and beyong the scope of discussion).
 The way it works that kernel has set up an interrupt handler for soft Int 0x80,
which means that whenever an interrupt like 0x80 occurs, the application
makes the transition to kernel space.
 
 The setup of 0x80 as interrupt handler is done through kernel function trap_init,
so when a syscall is called the function name and parameters to function are
 Copied to register and then interrupt 0x80 invoked. Once that is done the kernel
interrupt handler takes over and runs the corresponding function in kernel
 context fetching the argument from registers.
 
 The register EAX is used for passing the function name as well as the return
value from the function. If the function has arguments then depending on the
 number of argument one or more of the regsiters ebx, ecx, edx, esi, edi, ebp are
used. If the function has more than 6 arguments then its passed as a pointer to
 eax register. Before going into kernel mode the register values are saved using
the macro SAVE_ALL present in file arch/x86/kernel/entry_32.S or entry_64.S
 
 To execute and pass the call from user mode to
kernel you can either use the syscall API or write
your own assembly instruction.
 Syscall API included from sys/syscall.h does the
same thing, however copying the argument to
registers could be a hassle so it is left to the user to
explore and find out which way is more preferable.
 
 Let suppose we want to call a gettid API which
doen't have a corresponding glibc wrapper due to
portability issue, so this can be achieved by the
following
 code from man page of syscall
 Approach 1 using syscall API from glibc user library
 ----------------------------------------------------
 #include <sys/syscall.h>
 #include <sys/types.h>
 
 int main()
{
 pid_t tid;
 tid = syscall(SYS_gettid);
}
 
 Note: SYS_gettid is defined to be 224 in the glib header file
/usr/include/asm/unistd_32.h or unistd_64.h
 
 This number 224 may differ on your system as it depends on linux kernel as well
as the glibc version. So you can check and replace with the appropraite macro
 by hand or define on your own.
 
 i.e you can call in non-portable way as syscall(224).
 Approach 2 using the ASM Instructions
 --------------------------------------
 
 int mygettid()
{
 int status;
 __asm__("movl $224, %eax"); /* Ensure that the number 224
corresponds to*/
/*gettid in your header file */
 /*
 /usr/include/asm/unistd_32.h or use the one present */
 __asm__(“int $0x80");
 __asm__("movl %eax, -4(%ebp)");
 return status;
}
Steps to implement System Call in Linux kernel
 Download a copy of linux kernel 3.9.4 and extract it. I have extracted to location /usr/src/linux
 vi /usr/src/linux-3.9.4/arch/x86/syscalls/syscall_32.tbl
 Add the following line
 351 i386 psef sys_psef
 
 If you have 64 bit architecture then modify the file /usr/src/linux-3.9.4/arch/x86/syscalls/syscall_64.tbl
 
 
 
 
 vi /usr/src/linux-3.9.4/include/linux/syscalls.h
 add the following lines
 asmlinkage long sys_psef(void);
 
 
 In the following below code as part of psef.c we fetch process details like pid, task Name, thread group, state and priority.
 There is a kernel data structure called task_list which is a big struct having all the details related to process AKA task in
kernel terminology. This structure is included from <linux/sched.h> and its complete declaration could be obtained from
include/linux/sched.h.
 State is the state of the process whether its Stopped, runnable or
not-runnable.
 for_each_process is a kernel linked list which iterates through all
the process in system
 Modify/Create the following file.
 vi /usr/src/linux-3.9.4/kernel/psef.c
 
 
 #include <linux/kernel.h>
 #include <linux/sched.h>
 
 asmlinkage long sys_psef(void)
{
 struct task_struct *task_list;

 /* for_each_process is a macro which iterates through the entire list of task in system
 */
  
 /* You can have your kernel routine or task here defined instead of task details for psef */
 for_each_process(task_list)
 {
 printk(KERN_INFO "%d\t\t%s\t\t%d\t%ld\t%d\n",
 task_list->pid,
 task_list->comm,
 task_list->tgid,
 task_list->state,
 task_list->prio);
 }
  
 return 0;
}
 
 Note: You can have your own function as part of kernel or you can just have one liner printk for demo.
 
 5) vi /usr/src/linux-3.9.4/kernel/Makefile
 In the first section of MakeFile where obj-y is defined, add psef.o at the
end.
 
 
 It should look like obj-y = fork.o exec_domain.o panic.o printk.o \
 cpu.o exit.o itimer.o time.o softirq.o resource.o \
 sysctl.o sysctl_binary.o capability.o ptrace.o timer.o user.o \
 signal.o sys.o kmod.o workqueue.o pid.o task_work.o \
 rcupdate.o extable.o params.o posix-timers.o \
 kthread.o wait.o sys_ni.o posix-cpu-timers.o mutex.o \
 hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
 notifier.o ksysfs.o cred.o \
 async.o range.o groups.o lglock.o smpboot.o psef.o
 
 
 Note: We can have separate Makefile and component to build psef as a separate component. Refer to kernel Makefile
doc for the same for further info.
 
 
 
 
 
 Build the kernel, by running make config and make bzImage
 Load the newly build kernel. (Refer the Linux distro for the same)
 8) Write the application code(Equivalent of glibc wrapper) to call the system
call. Instead of modifying the header file unistd_32.h which sometimes require root access and any error to
this file can destabilize the system, we would wrap it with our own #define.
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/syscall.h>
 
 #define SYS_psef 351 /* Please ensure this number is the same as you wrote */
 /*in /usr/src/linux-3.9.4/arch/x86/syscalls/syscall_32.tbl*/
 
 int psef()
{
 printf("calling system call psef\n");
 return syscall(SYS_psef);
}
 
 int main()
{
 int ret;
 printf("Invoking System calls\n");
 ret = psef();
 if(ret < 0)
 exit(1);
 return 0;
}
 
 compile and run the psef.c as below
 gcc psef.c –o psef
 ./psef
 
 check the kernel ring buffer with dmesg and you would see the process
details using system call psef

You might also like