how to replace linux system call by module

33
Linux Replace Kernel Function with Module CGU NCTU aeifkz

Upload: yu-cheng-hsu

Post on 19-Jul-2015

185 views

Category:

Technology


7 download

TRANSCRIPT

Page 1: How to replace linux system call by module

Linux Replace Kernel Function with Module

CGU NCTU aeifkz

Page 2: How to replace linux system call by module

大綱

• 看這個可以讓我學到甚麼

• 看這個不會學到甚麼

• 動機

• 背景說明

• 實作 (包含編譯 Linux Kernel以及編寫 Linux Module)

• 結論

• 參考資料

Page 3: How to replace linux system call by module

看這個可以讓我學到甚麼

• 如何編譯 Linux kernel 及安裝

• 如何新增自己的 System Call

• 如何在 kernel 裡面放掛勾,之後利用 Module 去做修改

• 如何撰寫及編譯簡單的 Linux Module

Page 4: How to replace linux system call by module

看這個不會學到甚麼

• 為什麼是用這些方式新增 System Call (修改哪些檔案等等)

• 為什麼kernel 內的掛勾要用這樣的方式去宣告跟定義

• 這樣 Module 更改的方式有甚麼缺點?

• System Call 要怎麼設計(因為我給的範例真的是爛透了)

Page 5: How to replace linux system call by module

動機

• 某次修課必須在 Linux Kernel 底下定義自己的 System Call並且實做

• 但是編譯 Linux Kernel 並安裝實在很花時間,不好的筆電第一次編譯要2個多小時,之後再編也要大概半小時….

• 助教有給如何用 Linux Module的方式來實做,但是 Hint 給的實在太差,但我就是比較笨的學生,所以就自己重寫一篇

Page 6: How to replace linux system call by module

背景說明 – 為何要編自己的Kernel

• 可以自己修改 Linux Kernel code ,並且可以新增 System call 的方式提供不同的功能給 User 去使用

• 定義System Call 跟釋出自己的 C Library 有甚麼差別?

我自己是覺得System Call的功能是定義在作業系統層面,因此

1. 理論上作業系統內的任何程式語言都能夠使用這些System Call

(但目前我只會用C/C++去引入)

2. 實作上可以觸碰Linux Kernel 內部的一些結構或是Export 出來的變數

Page 7: How to replace linux system call by module

實做 – 新增System Call 及編譯 Kernel

• 環境 : VMware Player + Fedora 14

• 編譯Kernel版本 : 2.6.34.15

• 參考資料 : http://in1.csie.ncu.edu.tw/~hsufh/COURSES/FALL2007/syscall.html

• 以下都是按表操課,所以就只放指令、檔案跟截圖

Page 8: How to replace linux system call by module

實做

• 要先有 root 權限

• 下載 Linux Kernel 檔案並且解壓縮,最後切換目錄

• 之後的操作在目錄 /usr/src/kernels/linux-2.6.34.15 底下

cd /usr/src/kernels/wget https://www.kernel.org/pub/linux/kernel/v2.6/longterm/v2.6.34/linux-2.6.34.15.tar.xztar -xf linux-2.6.34.1cd linux-2.6.34.15

Page 9: How to replace linux system call by module

vim arch/x86/kernel/syscall_table_32.S

Page 10: How to replace linux system call by module

vim arch/x86/include/asm/unistd_32.h

Page 11: How to replace linux system call by module

vim arch/x86/include/asm/syscalls.h

Page 12: How to replace linux system call by module

vim arch/x86/kernel/hello.c

• 這邊定義了一個被呼叫除了會顯示一些訊息之外,還會回傳1的System Call

• 雖然這個設計爛到爆炸了,但是為了簡單起見,就先將就一下

Page 13: How to replace linux system call by module

vim arch/x86/kernel/Makefile

Page 14: How to replace linux system call by module

vim /usr/include/asm/unistd_32.h (工作目錄跟前面不一樣)

Page 15: How to replace linux system call by module

vim /usr/include/bits/syscall.h(工作目錄跟前面不一樣)

Page 16: How to replace linux system call by module

第一次編譯kernel,要等很久…

Page 17: How to replace linux system call by module

做完後重開機選擇編譯好的 kernel

Page 18: How to replace linux system call by module

寫支程式呼叫這個破爛的System Call…

#include <stdio.h>

#include<sys/syscall.h>

int main(void) {

printf( "system call hello return:%d.\n" , syscall(__NR_hello,2) );

return 0 ;

}

Page 19: How to replace linux system call by module

觀看一下System Call 輸出資訊

• 下指令 dmesg (printk 之訊息觀看的方式之一)

Page 20: How to replace linux system call by module

重點來了,編譯也太慢了吧…

• 假設編譯一次要30分鐘,一次Lab上課時間3個小時,代表開發者只能失手6次,要不然就要補交…

• 雖然助教提示了用 Linux Module 和 Export_SYMBOL 可以變成只透過 compile/insmod/rmmod 去做開發,但提示也太弱了吧

• 最後參考 reference (搜尋關鍵字 : linux EXPORT_SYMBOL override system call)

http://stackoverflow.com/questions/1196944/can-i-replace-a-linux-kernel-function-with-a-module

Page 21: How to replace linux system call by module

所以想法是怎樣?

• 在 Kernel Code 裡面埋下一個錨點 (不專業的術語),並且將其export 給其他 Kernel Code 或是 Kernel Module 去修改

• 錨點要怎麼定義跟埋?用 function pointer 去定義(至於為什麼用這個,就麻煩再另外google)

呼叫也要用 function pointer 方式去呼叫,要不然到時候 Module 額外修改定義不會生效

Page 22: How to replace linux system call by module

vim arch/x86/kernel/hello.c

錨點,並且把它指向kernel內部函式

多定義一個函式做跟原本一樣的事情

這邊要用錨點呼叫,若是用logic_sys_hello就沒救了

Export 錨點出來讓 Module 可以引入使用

要多 include module.h,要不然 EXPORT 會失敗

Page 23: How to replace linux system call by module

第二次編譯,指令少一些…還是要等有點久

• make

• make modules_install

• make install

•最後重開機….

Page 24: How to replace linux system call by module

呼叫破爛的System Call 及觀看結果

• 跟上一次結果應該都一樣,這證明了剛剛下的錨點不影響原本的邏輯

Page 25: How to replace linux system call by module

寫一個功能更爛的 Module (開一個新的資料夾來做)

• vim hello.c (part1)

#include <linux/kernel.h>

#include <linux/init.h>

#include <linux/module.h>

#include <linux/version.h>

MODULE_DESCRIPTION("My Hello World");

MODULE_LICENSE("GPL");

extern int (*p_sys_hello)(int) ;

static int (*tmp_sys_hello)(int) ;

外部引入EXPORT_SYMBOL的變數

暫存原本 kernel 內的定義

Page 26: How to replace linux system call by module

寫一個功能更爛的 Module• vim hello.c (part2)

int new_sys_hello( int i) {

printk(KERN_INFO "new system call => %d.\n",i) ;

return 100 ;

}

static int hello_init(void) {

printk(KERN_INFO "Hello, world\n");

tmp_sys_hello = p_sys_hello ;

p_sys_hello = &new_sys_hello ;

return 0;

}

新定義的System Call,會回傳100,很爛我知道

載入module會呼叫的函式,後面會看到設定

暫存原本的定義,替換成新的定義方式

Page 27: How to replace linux system call by module

寫一個功能更爛的 Module• vim hello.c (part3)

static void hello_exit(void) {

p_sys_hello = tmp_sys_hello ;

printk(KERN_INFO "Goodbye, cruel world\n");

}

module_init(hello_init) ;

module_exit(hello_exit);

卸載module會呼叫的函式,會回復原本定義

設定載入跟卸載 module要呼叫的函式

Page 28: How to replace linux system call by module

再寫一個Makefile• vim Makefile

obj-m += hello.o

KVERSION := $(shell uname -r)

all:

$(MAKE) -C /lib/modules/$(KVERSION)/build M=$(PWD) modules

clean:

$(MAKE) -C /lib/modules/$(KVERSION)/build M=$(PWD) clean

Page 29: How to replace linux system call by module

編譯及載入 module,最後看一下訊息

Page 30: How to replace linux system call by module

再次呼叫破爛的System Call 及觀看結果

• 太神奇啦~~~ 數值完全變了,而且不用重新編譯kernel

Page 31: How to replace linux system call by module

可以 rmmod hello.ko 再測試一次

• 結果會恢復到載入前的狀態,所以就不截圖了

Page 32: How to replace linux system call by module

結論

• 其實沒甚麼結論啦,就準備了一個比較友善的System Call的開發環境

• 至於要怎麼開發 System Call的功能、要把錨點下在哪比較好這些等等就要有勞其他大大分享心得了….

Page 33: How to replace linux system call by module

參考資料

• 輕輕鬆鬆學會Linux Kernel Module及TCP/IP 程式設計作者:謝進忠、謝進益, 出版社:全華圖書公司, 出版日期:2005-12-20

(如果你還借得到這本書的話,4.2 如何利用Module來修改Linux的網路核心程式也有提到)