如何在linux kernel 3.7中加入system call


作業系統有個加分作業,就是在linux kernel中加入自己的system call,我這科考試成積差,為了求分,我決定做這個加分作業。

為了讓這份功課公開後,可以在更長的時間內仍然有價值,我決定用最新的ubuntu 12.10 以及在當時推出了還不到兩天的kernel 3.7.2去完成這個作業,本教學同時適用於32bit和64bit linux。

(浪費了很多時間並經過一系列失敗後,給你的建議:教科書或者很多網站都是基於幾年前的2.6.X kernel,千萬不要照跟那些教學!!!現在的kernel和那個時代已不同!)

要在kernel中加入system call,你可以用git或者到kernel.org下載source code,Debian/Ubuntu 系列的話還可以用apt-get,不過apt-get通常都不是最新版,我這裏使用kernel 3.7.2。

下載完成後,解壓,我放在~/Desktop裏,要注意的是你要確保它所在的目錄你有足夠權限寫入,因為compile出來的kernel預設就是放在這個目錄。



  • 為方便,先建立一個soft link。
    ln -s linux-{your version} ~/Desktop/linux
    
  • 完成後,到~/Desktop/linux/arch/x86/kernel,建立一個叫helloworld.c的程式,這個就是我們的system call。
    #include <linux/linkage.h>
    #include <linux/kernel.h>
    
    asmlinkage int sys_helloworld(void) {
            printk(KERN_EMERG "By it.livekn.com");
    
            return 1;
    }
    
    
  • 編輯~/Desktop/linux/include/linux/syscalls.h,增加
    asmlinkage int sys_helloworld(void);
  • 編輯~/Desktop/linux/arch/x86/syscalls/syscall_32.tbl,在最後加上

  • 350     i386    helloworld              sys_helloworld
    注意:編號不一定為350,如果希望用在64bit的kernel上,請把syscall_32.tbl改成syscall_64.tbl,並把這行改成:
    350     common  helloworld              sys_helloworld



  • 編輯~/Desktop/linux/arch/x86/kernel/Makefile,加這一行:
    obj-y                   += helloworld.o
    


  • 上面的東西,是我被教科書和網上的舊教學騙了,經過一系列失敗後,花了一個下午找到的,接著便是時間更長的compile,方法請到這裏






  • 漫長的編譯完成(我編譯了超過4小時…),使用新kernel重新開機後,寫一個測試你system call的程式:
    #include <syscall.h>
    #include <sys/types.h>
    
    int main(void) {
            int a=syscall(350);
            return 0;
    }
    
    
  • 編譯及執行測試程式:
    gcc -o test test.c
    ./test
    
  • 輸入dmesg,看到最底有By it.livekn.com字樣嗎?

  • 也可以在/var/log/syslog裏看到

    恭喜,成功,我的Operating System課總分加5分!

    參考:Adding a new system call in Linux kernel 3.3 - Stack Overflow

    留言

    1. 最近實習課也出了這題..
      這篇對透過新版UBUNTU編譯上 很有幫助
      目前使用3.14版本 路徑上完全吻合
      但宣告CALL的括號部分 需要加個VOID或參數
      不然會在編譯時跳ERROR
      依照大大的範例的話 宣告要改成
      asmlinkage int sys_helloworld(void);

      回覆刪除
    2. Hello, 先謝謝你的教學, 3.19版路徑依然吻合,
      我想再請問一下有沒有辦法不用syscall直接呼叫呢?
      類似sys_helloworld(); 這樣,
      期待你的回答, 謝謝 ~

      回覆刪除

    張貼留言

    這個網誌中的熱門文章

    如何在ubuntu中compile kernel(12.10)