实验环境 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_alloc2 331 common pkey_free __x64_sys_pkey_free3 332 common statx __x64_sys_statx4 333 common io_pgetevents __x64_sys_io_pgetevents5 334 common rseq __x64_sys_rseq6 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 modulesmake modules_installmake installreboot
步骤六 测试系统调用
nano test.c
1 #include2 #include 3 #include 4 #include 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 012 pid:13 167514 nice1,prio21
EOF