1. 程式人生 > >給linux系統添加系統調用

給linux系統添加系統調用

錯誤 print x86 eval pan 新建 fin .cn 14.

實驗環境 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

給linux系統添加系統調用