通過內核編譯法向Linux內核添加系統調用


 

【實驗內容】:

  向Linux添加一個系統調用
  測試該系統調用
  使用 ptrace或類似的系統跟蹤工具來對該測試程序進行跟蹤調試

【軟件】:VMWare支持的Ubuntu虛擬機 VSCode

【步驟】

1.在實驗之前先下載好相關軟件包

不過如果升級了make以后,如果內核版本低,會報錯

1.    sudo apt-get install make  
2.    sudo apt-get install gcc  
3.    sudo apt-get install libncurses5-dev  
4.    sudo apt-get install flex  
5.    sudo apt-get install bison  
6.    sudo apt-get install libssl-dev  
7.    sudo apt-get install libelf-dev
2.進入 /usr/src下載內核源碼(實驗所用源碼為 linux-5.5.7)
內核5.5.7所需要的存儲空間特別大!!!一定要提前准備好!!!
1.    cd /usr/src  
2.    wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.5.7.tar.xz  

3.下載好之后在當前目錄進行解壓

1.    tar -xvf linux-5.5.7.tar.xz  

4.編寫系統調用的入口表

1.    sudo vim linux-5.5.7/arch/x86/entry/syscalls/syscall_64.tbl  

添加

1.    335     common      mysyscall        __x64_sys_mysyscall

 

 5.編寫系統調用函數聲明

1.    sudo vim linux-5.5.7/include/linux/syscalls.h

在里面添加

1.    asmlinkage long sys_mysyscall(int number);

 

 6.實現系統調用函數

1.    sudo vim linux-5.5.7/kernel/sys.c

在里面添加

1.    SYSCALL_DEFINE1(mysyscall, int, number) {  
2.        int result = number * number * number;  
3.        printk("The result is %d\n", result);  
4.        return 0;  
5.    }  

7.重新編譯內核

1.    cd linux-5.5.7/                            //進入內核文件夾
2.    sudo cp /usr/src/linux-headers-5.3.0-40-generic/.config /usr/src/linux-5.5.7 //復制內核配置
3.    make mrproper                                //刪除以前編譯產生的垃圾文件  
4.    make clean    
5.    make menuconfig                              //選擇Save保存再Exit
6.    make -j4                                     //編譯內核  
7.    make modules_install                         //安裝模塊  
8.    make install                                 //安裝內核  

 

 

 

 8.重啟選擇linux-5.5.7進入

(因為linux系統會自動選擇高版本內核加載,因此重啟虛擬機后加載的內核就是剛剛編譯完成的5.5.7內核)

 

 9. 編寫測試程序test.c驗證系統調用是否成功

1.    #include <stdio.h>  
2.    #include <sys/ptrace.h>  
3.    #include <sys/types.h>  
4.    #include <sys/wait.h>  
5.    #include <sys/user.h>  
6.    #include <sys/reg.h>  
7.    #include <sys/syscall.h>  
8.    #include <unistd.h>  
9.    #include <linux/kernel.h>  
10.      
11.    int main () {  
12.        syscall(335,4);  
13.        return 0;  
14.    }  

編譯執行后用dmsg查看結果

 

 正確噠!!!

10.用strace進行追蹤

 

 能看到系統調用成功

11.常見錯誤匯總!!

我太難了我編譯了五次才成功!

make首先,一定要在解壓好的文件夾里make,內核也一定解壓到那個文件夾!!!千萬不能自己創一個文件夾寫那個名字!!!我有個朋友這么干的哈哈哈哈

最常見的錯誤就是包沒裝全,如果報錯就裝就好了。

然后在make -4j之前,一定要檢查一下有沒有問題,因為make -4j一旦失敗enmmmmmm。。。我的方法就是不sudo輸入make -4j,這樣除了權限報錯以外,別的錯誤也會報錯

之后就是內核編譯的錯誤了

它是這樣報錯的:

[root@localhost module]# make 

make -C /opt/kangear/kernel/linux-2.6.32.2 M=/root/桌面/kangear/module modules

make[1]: Entering directory `/opt/kangear/kernel/linux-2.6.32.2'

 

  ERROR: Kernel configuration is invalid.

         include/linux/autoconf.h or include/config/auto.conf are missing.

         Run 'make oldconfig && make prepare' on kernel src to fix it.

 

 

  WARNING: Symbol version dump /opt/kangear/kernel/linux-2.6.32.2/Module.symvers

           is missing; modules will have no dependencies and modversions.

 

  Building modules, stage 2.

/opt/kangear/kernel/linux-2.6.32.2/scripts/Makefile.modpost:42: include/config/auto.conf: 沒有那個文件或目錄

make[2]: *** 沒有規則可以創建目標“include/config/auto.conf”。 停止。

make[1]: *** [modules] 錯誤 2

make[1]: Leaving directory `/opt/kangear/kernel/linux-2.6.32.2'

make: *** [all] 錯誤 2

[root@localhost module]# 

 

內核配置文件.config出錯。

可以參照一下這個博客https://blog.csdn.net/u013225150/article/details/48272853

另外,這個博客的錯誤我也都遇到了https://blog.csdn.net/stranger00001/article/details/84637032?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

然后總結一下我這五次編譯的卑微過程吧……
0.編譯前因為安裝包不全,在make -4j之前失敗了很多次
1.第一次編譯,因為在寫程序的時候用了for函數,編譯時並不支持,導致失敗
2.去掉for函數之后,顯示找不到配置的.config文件,發現make menuconfig的操作有誤,內核配置文件的命令輸入同樣錯誤,並沒有把內核配置成功復制
3.配置好內核,把所有相關包檢查升級后再次編譯,出現pkg錯誤,上網查資料后發現是make版本過高,一開始選擇的4.18內核不支持
4.選擇最新的5.5.7內核進行編譯,因為虛擬機空間不足報錯
5.不加sudo編譯時(即會報錯但因權限不足無法全部編譯,通過這種辦法節省時間查找錯誤)報錯arch/x86/Makefile:129: CONFIG_X86_X32 enabled but no binutils support,查找網上資料后說是缺少binutils支持,檢查更新沒有問題,之后找到方案在內核配置時選擇:
--> Device Drivers 
--> Multiple devices driver support (RAID and LVM)
--> Device mapper support
(這一項改為n)
再次編譯后成功。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM