天天看點

summery of adding system calls to linux kernel

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:   

  .data

  ENTRY(sys_call_table)

    .long SYMBOL_NAME(sys_ni_call)          

    .long SYMBOL_NAME(sys_exit)

    .long SYMBOL_NAME(sys_fork)

    ...

    .long SYMBOL_NAME(sys_vfork)            

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:

          #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/

myservice.h
#ifndef __LINUX_MYSERVICE_H
#define __LINUX_MYSERVICE_H
	
#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
      
myservice.c
#include <linux/myservice.h>
	
asmlinkage int sys_myservice (int arg1, char* arg2) {
    return(1);
/*
here asmlinkage indicates the linkage style of the syscall
which is defined in linux/linkage.h


*/
}
      
上一篇: Page fault

繼續閱讀