img applecjn

summery of adding system calls to linux kernel

发表于2004/11/1 14:32:00  614人阅读

To add a system call into linux kernel, follow the steps:
1. Preparation:  insert a new entry into the interrupt table.
     edit the file: linux/arch/i386/kernel/entry.S   in which lines look like:   
    .long SYMBOL_NAME(sys_ni_call)           /* 0 */
    .long SYMBOL_NAME(sys_exit)
    .long SYMBOL_NAME(sys_fork)
    .long SYMBOL_NAME(sys_vfork)             /* 190 */
after the line “ long SYMBOL_NAME(sys_vfork) “ you can add your own entry for your system call:
           . long   SYMBOL_NAME(sys_myService)
     Next, we define the the Num for our system call as a “stub”
    edit the file: linux/include/asm/unistd.h  in which lines look like:
            * This file contains the system call numbers.

          #define __NR_exit                 1
          #define __NR_fork                 2
          #define __NR_vfork              190
  Add your num define: 
          #define __NR_myService          191
2 Place for your  system call source file

After inserting your new system call entry in the interrupt table and preparing a stub for it, you will need to define (or implement) the system call. It will be easiest to have the system call definitions in your own source code files, say myservice.h and myservice.c.

In general, header files for machine architecture independent system calls and functions are kept under linux/include/linux/ and machine architecture dependent ones are kept in linux/include/asm/. Therefore, it would be a good idea to follow this convention. For example, the header file for the system calls for your new synchronization method, of which the implementation is machine architecture specific, would be placed in linux/include/asm/, while the header file for your machine architecture independent system call that access the superblock of one or more of your file systems would be placed under linux/include/linux.

The place for actual implementation file (myservice.c in this example) could vary. For example, if you are implementing a new process synchronization method, linux/ipc/ would be the best place for it. If you are implementing a file system related one, linux/fs/ would be the best place.

Remember that you will need to modify the Makefile in the directory you placed your .c file so that your code gets compiled and linked in properly. Modify the Makefile line to have a .o of your source code. For example, adding myservice.o:

  O_OBJS += ... myservice.o

The rest of the Makefiles can remain untouched (Makefile changes will be similar if you choose to add your code elsewhere).

3 . Implement the system call source file: 

Here is an example myservice.h and myservice.c, assuming myservice.h is under linux/include/linux/

#include <linux/unistd.h>
#include <linux/linkage.h>

_syscall2(int, myservice, int, arg1, char*, arg2);
/*the “2“ in “_syscall2“indicates the para number
of the syscall
  here the first para is the return type of syscall
2nd para is the name of the syscall
the next 2 para are paras passed to the syscall
*/ #endif
#include <linux/myservice.h>
asmlinkage int sys_myservice (int arg1, char* arg2) {
here asmlinkage indicates the linkage style of the syscall
which is defined in linux/linkage.h

*/ }


0 0


取 消