给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