天天看點

實驗一:Linux核心編譯及添加系統調用

實驗一:Linux核心編譯及添加系統調用

一、實驗目的

  • 了解Linux系統處理系統調用的流程
  • 增加一個系統調用

二、實驗内容

  • nice,可以了解為謙讓度,CPU在選擇程序時根據優先級prio選擇,當nice值越高,可了解為這個程序越是謙讓,即優先級越低
  • 添加一個系統調用,實作對指定程序的nice值的修改或讀取功能,并傳回系最新的nice值,即優先級prio。

    建議調用原型為:

    ​ Int mysetnice(pid_t pid, int flag, int nicevalue,void_userprio,void_usernice)

    ​ 參數含義:

    ​ pid:程序ID

    ​ flag:若值為0,表示讀取nice值;若值為1表示修改nice值。

    ​ prio,nice:指向程序目前優先級及nice值。

    ​ 傳回值:系統調用成功時傳回0,失敗時傳回錯誤碼EFAULT。

  • 寫一個簡單的應用程式測試系統調用
  • 深入閱讀相關函數源碼

三、流程圖

四、具體實作

  • 安裝虛拟機及ubuntu

    按指導來問題不大,在可行前提下,配置設定處理器選擇4核或以上

    大小配置設定60G左右!

    https://jingyan.baidu.com/article/f96699bb147a73894e3c1b2e.html

  • 開啟系統,打開terminal,進入管理者模式

    打開termintal: ctrl+alt+t

    管理者模式: 輸入 sudo su 輸入使用者密碼進入管理者模式

  • 下載下傳解壓核心

    下載下傳核心: 輸入 wget http://mirrors.ustc.edu.cn/kernel.org/linux/kernel/v4.x/linux-4.4.196.tar.xz

    解壓核心: 輸入 tar -xvJf linux-4.4.196.tar.xz

  • 系統調用

    裝各種包 輸入 sudo apt-get install vim libncurses5-dev make openssl libssl-dev bison flex ctags

實驗一:Linux核心編譯及添加系統調用

添加系統調用号 進入核心:cd linux-4.4.196 # 之後的操作都是在這個目錄下

​ 編輯調用表:vim arch/x86/entry/syscalls/syscall_64.tbl

​ 輸入G (跳末行)上行到300多行 ,輸入i (進入編輯模式)

​ 輸入如圖

實驗一:Linux核心編譯及添加系統調用

​ 按ESC鍵 退出編輯模式 輸入 :wq 儲存并退出

申明系統調用 vim include/linux/syscalls.h

​ 輸入 G i 添加如下

​ 按ESC鍵 退出編輯模式 輸入 :wq 儲存并退出

實作調用 vim kernel/sys.c

​ 輸入 G i 添加如下

SYSCALL_DEFINE5 (mysetnice,pid_t,pid,int,flag,int,nicevalue,void __user*,prio,void __user*,nice){
    //SYSCALL_DEFINEN中N表示系統調用所需要的參數個數,我們的是5個
     struct task_struct *p;//程序結構體指針
     struct pid *id;//pid結構體
     int m,n;
     id=find_get_pid(pid);//通過傳入的pid_t pid得到id結構體 
     p=pid_task(id,PIDTYPE_PID);//通過id得到指定程序,PIDTYPE_PID指的是程序類型的pid 
     m=task_nice(p);     //通過p得到nice值 
     n=task_prio(p);     //通過p得到prio值(優先級) 
     if(flag==0){//讀取 
        copy_to_user(nice,(void*)&m,sizeof(m));//将m的位址強轉為void *類型 
        copy_to_user(prio,(void*)&n,sizeof(n));
        return 0;
     }
     else if(flag==1){//修改 
        printk("nice value before modified:%d\n",m); 
        set_user_nice(p,nicevalue);//修改nice的值
        return 0;
     } 
     printk("syscall failed!");
     return EFAULT; 
}
           

​ 按ESC鍵 退出編輯模式 輸入 :wq 儲存并退出

  • 配置編譯核心

    輸入 make mrproper

    輸入 make clean

    輸入 make menuconfig

    (terminal視窗最大化)

    選擇Save 回車确定 回車确定 選擇Exit

實驗一:Linux核心編譯及添加系統調用

輸入 make -j4

​ (-j4表示4線程編譯,耗費較長,無視warning,跳出error可以ctrl+c結束了,出錯了就沒必要再編譯了,看看是否漏掉步驟,根據跳出的error解決)

  • 安裝核心重新開機系統

    輸入 make modules

    輸入 make modules_install

    輸入 make install

    輸入 update-grub2

    輸入 reboot

    重新開機後 ctrl+alt+t 打開terminal 輸入 sudo su 進入管理者模式

    輸入 uname -a 如果顯示的是下載下傳的核心 這裡是4.4.196 表明編譯成功

  • 編寫函數測試用

    輸入 vim exp_1_test.c 建立C檔案測試調用

    輸入i (進入編輯模式)

    編寫代碼如下

    #include<stdio.h>
    #include<unistd.h>
    #include<sys/syscall.h>
    #define __NR_mysyscall 326
    int main(){
            int nice,prio;
            pid_t id;
    	    id=getpid();
    
            printf("----------------read-----------------\n\n");
            syscall(__NR_mysyscall,id,0,NULL,&prio,&nice);
            printf("before modified:pid:%d,prio:%d,nice:%d\r\n",id,prio,nice);
    
    
            printf("-----------------set-------------------\n\n");
            printf("syscall(__NR_mysyscall,id,1,-8,&prio,&nice);\n");
            syscall(__NR_mysyscall,id,1,-8,&prio,&nice);
    
            printf("------------------read-----------------\n\n");
            syscall(__NR_mysyscall,id,0,NULL,&prio,&nice);
            printf("modified:pid:%d,prio:%d,nice:%d\r\n",id,prio,nice);
            return 0;
    }
               

    ​ 按ESC鍵 退出編輯模式 輸入 :wq 儲存并退出

    輸入 gcc exp_1_test.c 編譯C檔案

    輸入 ./a.out 檢視結果

  • 相關核心源碼閱讀

    輸入 cd linux-4.4.196 進入目錄

    輸入 sudo ctags -R * (一些準備工作)

    輸入 vim kernel/sys.c 就是之前實作調用的

    這裡以檢視set_user_nice函數及nice定義為例,可以此類推

實驗一:Linux核心編譯及添加系統調用

這裡光标移動到如圖 set_user_nice 函數

輸入 ctrl + ] 進入函數 (退出則是c trl +T)

顯示如圖

實驗一:Linux核心編譯及添加系統調用

光标移動到 MIN_NICE 輸入 ctrl + ] 進入

顯示如圖

實驗一:Linux核心編譯及添加系統調用

繼續閱讀