• [Fw]How to Add a System Call(Fedora Core 6 Kernel : 2.6.18)


    How to Add a System Call

    Kernel : 2.6.18
    編譯環境 : Fedora Core 6


    假設要加的system call為 sys_project, 有一個int的輸入參數
    一、在linux source code的部份(以 linux 代表source code的根目錄)

    1. linux/arch/i386/kernel/syscall_table.S的最後面加上要新增的system call名稱
      如果syscall_table.S的最後面長得像這樣
              .
              .
      .long sys_tee                   /* 315 */
      .long sys_vmsplice
      .long sys_move_pages
      那麼要加入sys_project就要把它改成這樣, 這裡的".long"是必須的, 它並不是代表回傳的型態, 而是Linux Assembly的一個語法
              .
              .
      .long sys_tee                   /* 315 */
      .long sys_vmsplice
      .long sys_move_pages
      .long sys_project             /* 318 */
      而所加的定義在檔案中的順序, 其實也就是這個system call的system call number, 此例中是318
    2. linux/include/asm/unistd.h裡面加上自己的define
      unistd.h裡面會有一段跟syscall_table.S很像的define, 不過在這裡system call是以"__NR_"開頭, 而其後跟著的數值則是system call number, 如果在它定義的最後一個system call附近像這樣
              .
              .
      #define __NR_vmsplice               316
      #define __NR_move_pages         317

      #ifdef __KERNEL__

      #define NR_syscalls 318
              .
              .
      因為 NR_syscalls 的值必須等於最大的system call加 1, 所以在根據syscall_table.S中的順序修改unistd.h之後, 不要忘了修改NR_syscalls的值
              .
              .
      #define __NR_vmsplice               316
      #define __NR_move_pages         317
      #define __NR_project                  318

      #ifdef __KERNEL__

      #define NR_syscalls 319
              .
              .
    3. linux/include/linux/syscalls.h裡面加上函式的定義
      函式定義前面必須加上asmlinkage以確保編譯時連結的正確性, 所以加完後的狀況大概像這樣
              .
              .
      asmlinkage long sys_set_robust_list(struct robust_list_head __user *head,
              size_t len);
      asmlinkage long sys_project( int i );

      #endif
    4. 將system call的實作檔放入source code tree中
      原則上, 實作檔應該根據 syscall 的類型放在相對應的資料夾中, 然後再將實作檔編譯後的.o檔檔名加入該資料夾下的Makefile的obj-y之中, 假設實作檔的source code為project.c, 放在linux/kernel/, 那linux/kernel/Makefile改完後大概長這樣
              .
              .
      obj-y = project.o sched.o fork.o exec_domain.o panic.o printk.o profile.o
              .
              .
      而在撰寫實作檔的時候, 請記得將"#include <linux/linkage.h>"加進去, 否則編譯將會發生問題, 以下是一個實作檔的範例
      project.c
      #ifndef __LINUX_PROJECT
      #define __LINUX_PROJECT

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

      asmlinkage long sys_project( int i ){
              printk( "Success!! -- %d ", i );
              return 0;
      }

      #endif
    5. 在/usr/include/asm/unistd.h中加入定義讓User能呼叫
      其實在上一步驟整個system call已經算是加好了, 但此時User只能以system call number呼叫(此例中是318), 為了讓User能以system call的名字呼叫, 所以要修改/usr/include/asm/unistd.h,改完結果像這樣
              .
              .
      #define __NR_vmsplice              316
      #define __NR_move_pages        317
      #define __NR_project                 318

      #endif /* _ASM_I386_UNISTD_H_ */
    6. 重新編譯Kernel---->大功告成!!!

    二、如何呼叫System call
    要呼叫system call, 必須加入"#include<syscall.h>", 並以syscall( __NR_[system call的名字], [參數1, 參數2,...] )來呼叫, 如果沒有做步驟 5, 則必須以syscall( [system call number], [參數1, 參數2,...] )來呼叫, 以下是一個範例

    test.c
    #include<syscall.h>

    int main(){
            syscall( __NR_project, 2 );
            /* 如果沒有做步驟 5, 就用syscall( 318, 2 ); 代替 */
            return 0;
    }

    執行結果

    [root@localhost test]# gcc test.c
    [root@localhost test]# ./a.out
    [root@localhost test]# dmesg
            .
            .
            .
    Success!! -- 2
    [root@localhost test]#
     
     
     
     

    ---------
    linux/include/linux/syscalls.h
    task_struct

    asmlinkage long sys_project(char *test_array,char *test_array_tail,int operation);


    ----------
    How to Add a System Call
    假設要加的system call為 sys_project, 有一個int的輸入參數
    注意有些地方該是sys_開頭(syscalls.h)

    In source code 的根目錄:
    arch/i386/kernel/syscall_table.S
    include/asm-i386/unistd.h
    include/linux/syscalls.h
    kernel/Makefile
    系統根目錄
    /usr/include/asm/unistd.h

    來源:

    http://adl.csie.ncu.edu.tw/~ernieshu/syscall_2_6_35.htm
    http://adl.csie.ncu.edu.tw/~ernieshu/syscall.htm

  • 相关阅读:
    关于篮球🏀
    Docker学习笔记
    Java中的强引用,软引用,弱引用,虚引用
    MySQL:show process
    航空航天概论复习
    【Shell技巧】shell统计文件夹下的文件个数、目录个数 Don't use ls | grep. Use a glob or a for loop with a condition to allow nonalphanumeric filenames.
    【Shell技巧】以空格分隔的字符串解析成数组 Prefer mapfile or read a to split command output (or quote to avoid splitting).
    【Shell Check】Useless cat. Consider 'cmd < file | ..' or 'cmd file | ..' instead.
    【Shell技巧】清理文件内的所有文件以及 Use "${var:?}" to ensure this never expands to /* .
    【go语言基础】函数
  • 原文地址:https://www.cnblogs.com/bittorrent/p/3330803.html
Copyright © 2020-2023  润新知