830 likes | 2.15k Views
System Calls. Biju K Raveendran CS / IS Group, BITS Pilani. Why we need protection?. In single task / programming environment To protect OS from incorrect program In multiprogramming / multitasking environment To protect OS and other programs from incorrect program.
E N D
System Calls Biju K Raveendran CS / IS Group, BITS Pilani.
Why we need protection? • In single task / programming environment • To protect OS from incorrect program • In multiprogramming / multitasking environment • To protect OS and other programs from incorrect program
How to Protect the system • Hardware Protection or Software Protection? How ? • Preferably Hardware (fast and effective) • Dual-Mode Operation • 1.User mode – execution done on behalf of a user. • 2.Monitor mode (also supervisor mode or system mode) – execution done on behalf of operating system. • Mode bit (one bit) added to computer hardware to indicate the current mode: monitor (0) or user (1). • Interrupt or fault handling in monitor mode • Privileged instructions can be issued only in monitor mode
How to communicate ? • How to communicate between two modes? • System calls • Provide the interface between a running program and the operating system. • Only legal entry point to the kernel. • Provides an abstract hardware interface for user space to request service from OS • Application need not worry about type of disk, media and file system in use • Ensures system stability and security. • Kernel can keep track of application’s activity(resource usage).
The process fills the registers with the appropriate values and calls a special instruction which jumps to a previously defined location in the kernel • Under Intel CPUs, this is done by means of interrupt 0x80. • $0x80 triggers a switch to kernel mode and the execution of exception vector 128 (system call handler) • System call handler • Is the function which is architecture dependent and is available in entry.S • Reads the value of EAX. • Checks the validity of the given system call number by comparing it to NR_syscalls (syscall_table.S). • If could not find, the function returns –ENOSYS. • Otherwise specified system call is invoked Call *sys_call_table(,%eax,4) each system call table entry is 32 bits, the kernel multiplies the given system call number by 4 to arrive at its location in system call table.
fscanf system call execution Call to read() read() in C program read() in the C library read system call
call read() read() wrapper system_call() sys_read() Application C library read() wrapper System call handler sys_read() User Space Kernel Space Invoking system call handler & executing system call
Execution flow • When a user invokes a system call, execution flow is as follows: • Each call is vectored through a stub in libc. • Each call within the libc library is generally a syscallX() macro (can find in /usr/include/asm-i386/unistd.h), where X is the number of parameters used by the actual routine ( in to the system call). • Macro should know number of parameters passing in to system call (all of them pushed in to registers, totally 2+2*n parameters) • Eg. long open (const char *filename, int flags, int mode) #define NR_open 5 _syscall3 (long, open, const char *, filename, int, flags, int, mode) • Even complex system calls (because of variable length argument lists, e.g. open(), ioctl()), must use the same entry point
Execution flow continues .. • Each syscall macro expands to an assembly routine which sets up the calling stack frame and calls _system_call() through an interrupt, via the instruction int 0x80. • At this point no system code for the call has been executed. Not until the int 0x80 is executed does the call transfer to the kernel entry point _system_call(). • It is responsible for saving all registers, checking to make sure a valid system call was invoked and then ultimately transferring control to the actual system call code via the offsets in the _sys_call_table. • It is also responsible for calling _ret_from_sys_call() when the system call has been completed, but before returning to user space.
Execution flow continues .. • Actual code for many of the system calls can be found in /usr/src/linux/kernel/sys.c. • After the system call has executed, _ret_from_sys_call() is called. It checks to see if the scheduler should be run, and if so, calls it. • Upon return from the system call, the syscallX() macro code checks for a negative return value, and if there is one, puts a positive copy of the return value in the global variable _errno, so that it can be accessed by code like perror()
System call implementation • What is the purpose of new system call? • If possible it should have only one purpose • What are the new system call’s arguments, return value and error codes? • Is it portable and robust? • Verifying system call parameters • Ensure it is valid and legal • Important to check the validity of pointers a user gives • Before following a pointer into user space, the system must ensure • The pointer points to a region of memory in user space • The pointer points to a region of memory in the process’s address space • If reading, memory is marked readable. If writing memory is marked writable.
For writing in to user space copy_to_user()is provided with 3 parameters • Destination address space • Source pointer in kernel space • Size in bytes of the data to copy • For reading from the user space copy_from_user()is provided with same parameters as copy_to_user() • Both these functions return the number of bytes they failed to copy on error, zero on success. • System call will return –EFAULT in case of error.
Example asmlinkage long sys_silly_copy (unsigned long *src, long *dst, unsigned long len) { unsigned long buf; if(len!=sizeof(buf)) return –EINVAL; If(copy_from_user(&buf, src, len)) return –EFAULT; If(copy_to_user(dst, &buf, len)) return –EFAULT; return len; } asmlinkage Compiler will look only in stack for this function’s arguments
Binding a system call • Add an entry to the end of system call table (in syscall_table.S). • .long sys_foo • For each architecture supported, the syscall number needs to be defined in include/asm/unistd.h #define __NR_foo 318 #define NR_syscalls 319 • In include/asm/syscalls.h add the following line at the end of the file asmlinkage long sys_foo();
Binding a System Call Continue • The system call needs to be compiled into kernel image. This can be as simple as putting putting the system call in a relevant file in kernel. • Implement the actual foo() system call • Put it in kernel/sys.c (put it where ever the function is most relevant or implement in separate file). E.g. in sched.c if the function is scheduling related.
foo( ) system call implementation foo.h #ifndef __LINUX_FOO_H #define __LINUX_FOO_H #include <linux/linkage.h> #endif foo.c #include<linux/foo.h> asmlinkage long sys_foo() { return –ENOMEM; } User space can now invoke foo() system call.
foo( ) system call implementation conti .. foo-user.h #include <linux/unistd.h> #define __NR_foo 317 _syscall0(long, foo) user-app.c #include <sys/foo-user.h> #include<stdio.h> int main(void) { printf(“%d\n”,foo( ); return 0; }
Testing the new System Call • Recompile and install the new kernel • Compile and Execute the user space C file (user-app.c)
Difference between System call and function call • System call typically accessed via function calls. • System call involves context switching (from user to kernel and back) where as function call does not. • Takes much longer time than subroutine (function) calls. • Avoiding excessive system calls might be a wise strategy for programs that need to be tightly optimized. • Most of the system calls return a value (error if failed) where as it is not necessary for subroutine. • If an error (return value –1) use perror (“Message”) to print the error.
Pros and Cons of system calls • Pros • Simple to implement and easy to use • In Linux it is very fast • Cons • Need a system call number, which needs to be officially assigned to you during the developmental kernel series. • Once stabilized, the interface can not change with out breaking user space application • Each architecture needs to separately register the system call and support it. • For simple exchanges of information, a system call is overkill (overheads because of cache miss and context switch)
System calls for low level file I/O creat(name, permissions), open(name, mode), close(fd), unlink(fd), read(fd, buffer, n_to_read), write(fd, buffer, n_to_write), lseek(fd, offest, whence) System Calls for process control fork(), wait(), execl(), execlp(), execv(), execvp(), exit(), signal(sig, handler), kill(sig, pid) System Calls for IPC pipe(fildes), dup(fd)
Information about system calls and library routines • man 2 read (if read is a system call) • man 3 read (if read is a library routine)