给linux系统添加系统调用

实验环境 debian-9.8.0-amd64

步骤一 准备内核源代码

1 wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.20.14.tar.xz

或者使用国内镜像以加快下载速度

1 wget https://mirror.tuna.tsinghua.edu.cn/kernel/v4.x/linux-4.20.14.tar.gz

使用tar -xvf 命令解压

步骤二 修改系统调用表 

cd linux-4.20.14
nano ./arch/x86/entry/syscalls/syscall_64.tbl

找到一个空闲的系统调用号,新建一项系统调用

1 330    common    pkey_alloc      __x64_sys_pkey_alloc
2 331    common    pkey_free       __x64_sys_pkey_free
3 332    common    statx           __x64_sys_statx
4 333    common    io_pgetevents   __x64_sys_io_pgetevents
5 334    common    rseq            __x64_sys_rseq
6 335    common    foo             __x64_sys_foo

步骤三 声明系统调用服务例程

1 nano ./include/linux/syscalls.h
1 asmlinkage long sys_foo(pid_t pid,int flag,int nicevalue,void __user* prio,void __user* nice);

步骤四 实现服务例程

1 nano ./kernel/sys.c 
 1 SYSCALL_DEFINE5(foo,pid_t,pid,int,flag,int,nicevalue,void __user*,prio,void __user*,nice){
 2     struct pid * kpid;
 3     struct task_struct * task;
 4     kpid = find_get_pid(pid);
 5     task = pid_task(kpid,PIDTYPE_PID);
 6     int dwnice = task_nice(task);
 7     int dwprio = task_prio(task);
 8     if(flag == 1){
 9         set_user_nice(task,nicevalue);
10         dwnice = task_nice(task);
11         copy_to_user(nice,&dwnice,sizeof(dwnice));
12         copy_to_user(prio,&dwprio,sizeof(dwprio));
13         return 0;
14     }
15     else if (flag == 0){
16         copy_to_user(nice,&dwnice,sizeof(dwnice));
17         copy_to_user(prio,&dwprio,sizeof(dwprio));
18         return 0;
19     }20     return EFAULT;
21 }

步骤五 编译内核

编译内核中会遇到一些依赖未安装的问题,一般按照错误提示解决即可。

make menuconfig #如果一切正常,会出现一个蓝色界面 保持默认设置 save exit exit 即可
make        #make时间会很长
make modules
make modules_install
make install
reboot

步骤六 测试系统调用

nano test.c
 1 #include <unistd.h>
 2 #include<sys/syscall.h>
 3 #include<stdio.h>
 4 #include<stdlib.h>
 5 int main(){
 6     pid_t pid;
 7     int nicevalue = 0;
 8     int flag;
 9     int p = 0;
10     int n = 0;
11     printf("flag:\n");
12     scanf("%d",&flag);
13     printf("pid:\n");
14     scanf("%d",&pid);
15     if(flag == 1){
16         printf("nice:\n");
17         scanf("%d",&nicevalue);
18     }
19     syscall(335,pid,flag,nicevalue,&p,&n);
20     printf("nice%d,prio%d\n",n,p);
21     return 0;
22 }
 1 root@debian:~/test$ ./a.out 
 2 flag:
 3 1
 4 pid:
 5 1675
 6 nice:
 7 1
 8 nice1,prio20
 9 root@debian:~/test$ ./a.out 
10 flag:
11 0
12 pid:
13 1675
14 nice1,prio21

 

EOF

上一篇:JavaScript实现剪切板复制功能


下一篇:Python 函数参数