Presentation is loading. Please wait.

Presentation is loading. Please wait.

Implementing System Calls CS552 Kartik Gopalan. CS552/BU/Spring2008 Steps in writing a system call 1.Create an entry for the system call in the kernel’s.

Similar presentations


Presentation on theme: "Implementing System Calls CS552 Kartik Gopalan. CS552/BU/Spring2008 Steps in writing a system call 1.Create an entry for the system call in the kernel’s."— Presentation transcript:

1 Implementing System Calls CS552 Kartik Gopalan

2 CS552/BU/Spring2008 Steps in writing a system call 1.Create an entry for the system call in the kernel’s syscall_table  User processes trapping to the kernel (through SYS_ENTER or int 0x80) find the syscall function through this table. 2.Write the system call code as a kernel function  Be careful when reading/writing to user-space  Use copy_to_user or copy_from_user routines 3.Generate/Use a user-level system call stub  Hides the complexity of making a system call from user applications.

3 CS552/BU/Spring2008 Step 1: Create a sys_call_table entry  /usr/src/redhat/BUILD/kernel- 2.6.18/linux- 2.6.18.s390x/arch/s390/kernel/syscalls.S // for a z/390 kernel) #define NI_SYSCALL SYSCALL(…) syscall (sys_fork, sys_fork, sys_fork) ● ● ● syscall(sys_mysvc, sys_mysvc, sys_mysvc)  arch/x86/kernel/syscall_table_32.S //for a PC kernel ENTRY(sys_call_table).long sys_restart_syscall /* 0 */.long sys_exit.long sys_fork.long sys_read ● ● ●.long sys_unshare /* 310 */.long sys_foo /* 311 */  include/asm/unistd_32.h /* * This file contains the system call numbers. */ #define __NR_restart_syscall 0 #define __NR_exit 1 #define __NR_fork 2 #define __NR_read 3 #define __NR_write 4 … #define __NR_foo 325 #define NR_syscalls 326 /* increment by one */

4 CS552/BU/Spring2008 Step 2: Write the system call (1)  No arguments, Integer return value asmlinkage int sys_foo(void) { printk (KERN ALERT “I am foo. UID is %d\n”, current->uid); return current->uid; }  Note: no comma after KERN ALERT  One primitive argument asmlinkage int sys_foo(int arg) { printk (KERN ALERT “This is foo. Argument is %d\n”, arg); return arg; }

5 CS552/BU/Spring2008 Step 2: Write the system call (2)  Verifying argument passed by user space asmlinkage long sys_close(unsigned int fd) { struct file * filp; struct files_struct *files = current- >files; struct fdtable *fdt; spin_lock(&files->file_lock); fdt = files_fdtable(files); if (fd >= fdt->max_fds) goto out_unlock; filp = fdt->fd[fd]; if (!filp) goto out_unlock; … out_unlock: spin_unlock(&files->file_lock); return -EBADF; }  Call-by-reference argument o User-space pointer sent as argument. o Data to be copied back using the pointer. asmlinkage ssize_t sys_read ( unsigned int fd, char __user * buf, size_t count) { … if( !access_ok( VERIFY_WRITE, buf, count)) return –EFAULT; … }

6 CS552/BU/Spring2008 Example syscall implementation asmlinkage int sys_foo(void) { static int count = 0; printk(KERN_ALERT "Hello World! %d\n", count++); return -EFAULT; // what happens to this return value? } EXPORT_SYMBOL(sys_foo);

7 CS552/BU/Spring2008 Step 3: Generate user-level stub Using your new system call - the new way  Old macros _syscall0, _syscall1, etc are now obsolete in the new kernels.  The new way to invoke a system call is using the the syscall(...) library function.  Do a "man syscall" for details.  For instance, for a no-argument system call named foo(), you'll call  ret = syscall(__NR_sys_foo); // Assuming you've defined __NR_sys_foo earlier  For a 1 argument system call named foo(arg), you call  ret = syscall(__NR_sys_foo, arg);  and so on for 2, 3, 4 arguments etc.  For this method, check  http://www.ibm.com/developerworks/linux/library/l-system-calls/

8 CS552/BU/Spring2008 Using your new system call - the new way (contd.) #include // define the new syscall number. Standard syscalls are defined in linux/unistd.h #define __NR_sys_foo 311 // or add this to unistd.h int main(void) { int ret; while(1) { // making the system call ret = syscall(__NR_sys_foo); printf("ret = %d errno = %d\n", ret, errno); sleep(1); } return 0; }

9 CS552/BU/Spring2008 Using your new system call - the old way  You can still replicate the old _syscall0, _syscall1 etc assembly code stubs in your user program, but this is really not necessary anymore.  These stubs use the old method of raising "int 0x80" software interrupts  which are found to be quite slow on newer Pentium machines.  But this technique still works for backward compatibility.  For this method, check http://www.linuxjournal.com/article/1145

10 CS552/BU/Spring2008 Using your new system call - the old way (contd.)  _syscall0(type,name)  type : type of return value (e.g. void or int)  name : name of the system call (e.g. foo)  _syscall0(int,foo)  Defines syscall entry point for “asmlinkage int sys_foo(void)”  _syscall1(type,name,type1,arg1)  type and name same as before  type1 : type of first argument  name1 : name of first argument  _syscall1(void,foo,int,arg)  Defines syscall entry point for “asmlinkage void sys_foo(int arg)”  … and similarly for two arguments, three arguments and so on.  For definitions of _syscallN macros, check  include/asm/unistd.h  Also, pay attention to the usage and implementation of __syscall_return macro. What does it do?

11 CS552/BU/Spring2008 Using your new system call - the old way (contd.) #include // define the new syscall number. Standard syscalls are defined in linux/unistd.h #define __NR_foo 311 // generate a user-level stub _syscall0(int,foo) int main(void) { int ret; while(1) { // making the system call ret = foo(); printf("ret = %d errno = %d\n", ret, errno); sleep(1); } return 0; }

12 CS552/BU/Spring2008 SYSENTER/SYSEXIT Method  This is the newest and fastest of all methods to make system calls in Pentium class machines.  Pentium machines have long supported these new instructions as a faster technique to enter and exit the kernel mode than the old technique based on raising the "int 0x80" software interrupt. Newer linux kernels have apparently adopted this technique.  The details of how this works is quite interesting and I may try to cover this briefly in the class.  Meanwhile you can read about the details in the following links and maybe even try it out using the example code.  http://manugarg.googlepages.com/systemcallinlinux2_6.html  http://www.win.tue.nl/~aeb/linux/lk/lk-4.html  http://manugarg.googlepages.com/aboutelfauxiliaryvectors

13 CS552/BU/Spring2008 Files to change in Redhat Linux  /usr/src/redhat/BUILD/kernel-2.6.18/linux- 2.6.18.s390x/arch/s390/mm/fault.c o Your kernel function implementation goes here (actual function code)  /usr/src/redhat/BUILD/kernel-2.6.18/linux- 2.6.18.s390x/arch/s390/kernel/syscalls.S o SYSCALL(sys_mysvc, sys_mysvc, sys_mysvc); // typical entry  /usr/src/redhat/BUILD/kernel-2.6.18/linux- 2.6.18.s390x/include/asm-s390/unistd.h o #define __NR_mysvc n and #define __NR_syscalls n+1  /usr/src/kernels/2.6.18-92.el5-s390x/include/asm-s390/unistd.h o Same as the BUILD UNISTD.H -------- following are for a PC build, not S390 ----------  /usr/include/asm/unistd.h  /usr/src/redhat/BUILD/kernel-2.6.18/linux- 2.6.18.s390x/arch/i386/kernel/syscall_table.S o.long sys_mysvc


Download ppt "Implementing System Calls CS552 Kartik Gopalan. CS552/BU/Spring2008 Steps in writing a system call 1.Create an entry for the system call in the kernel’s."

Similar presentations


Ads by Google