Linux 实用小代码,自定义一个系统调用

Linux 是一个开源的系统,我们可以根据需要,添加一个自定义的系统调用,完成所需要的动作。

1 环境

  • Red Hat Enterprise Linux release 7.6
  • linux-3.10.0-957.5.1.el7.x86_64

2 具体步骤

2.1 将需要添加的系统调用号与调用函数的对应到文件 “syscall_64.tbl”

  • 路径
    1
    linux-3.10.0-957.5.1.el7.x86_64/arch/x86/syscalls/syscall_64.tbl
  • 格式
    1
    Format: <number> <abi> <name> <entry point>
  • 添加的示例
    1
    2000 common Sam sysSam

    2.2 将我们具体要实现的系统调用到文件 “syscalls.h”

  • 路径
    1
    Path: linux-3.10.0-957.5.1.el7.x86_64/include/linux/syscalls.h
  • 添加的示例
    1
    asmlinkage long sysSam(int count);

    2.3 将我们具体要实现的系统调用号到文件 “unistd.h”

  • 路径
    1
    Path: linux-3.10.0-957.5.1.el7.x86_64/include/uapi/asm-generic/unistd.h
  • 添加的示例
    1
    2
    #define __NR__sysSam 2000
    __SYSCALL(__NR__sysSam, sysSam)

    2.4 将我们具体要实现的系统调用的具体实现到文件 “sys.c”

  • 路径
    1
    Path: linux-3.10.0-957.5.1.el7.x86_64/kernel/sys.c
  • 添加的示例
    1
    2
    3
    4
    5
    6
    7
    asmlinkage long sysSam(int count){
    int i;
    for (i=0; i<count; i++){
    printk(KERN_ALERT " ## Sam system call test %d \n", i);
    }
    return 0;
    }

    2.5 重新编译并且加载我们的内核

  • 就是常规的make bzImage 在reboot 就好了
    1
    3.10.0.Sam #3 SMP Sat Mar 20 09:19:47 CST 2019x86_64 x86_64 x86_64 GNU/Linux

    2.6 写一个简单的应用来调用我们的系统调用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <stdio.h>
    #include <unistd.h>
    int main(int argc, char **argv){
    int ret=1;
    /* use system call number directly and pass parameter 3*/
    ret=syscall(2000,3);
    printf("ret = %d\n", ret);
    return ret;
    }

    2.7 编译并且执行我们的应用

  • 编译
    1
    # gcc -g samSystemCallTest.c -osamSystemCallTest
  • 执行
    1
    # ./samSystemCallTest
  • 输出
    1
    2
    3
    [ 107.667182]  ## Sam system call test 0
    [ 107.667241] ## Sam system call test 1
    [ 107.667277] ## Sam system call test 2