20135327--linux內核分析 實踐二

內核模塊編譯

一、實驗原理

Linux模塊是一些能夠做爲獨立程序來編譯的函數和數據類型的集合。之因此提供模塊機制,是由於Linux自己是一個單內核。單內核因爲全部內容都集成在一塊兒,效率很高,但可擴展性和可維護性相對較差,模塊機制可彌補這一缺陷。linux

Linux模塊能夠經過靜態或動態的方法加載到內核空間,靜態加載是指在內核啓動過程當中加載;動態加載是指在內核運行的過程當中隨時加載。shell

一個模塊被加載到內核中時,就成爲內核代碼的一部分。模塊加載入系統時,系統修改內核中的符號表,將新加載的模塊提供的資源和符號添加到內核符號表中,以便模塊間的通訊。函數

二、編寫模塊代碼

  • 模塊構造函數:
    •   執行insmod或modprobe指令加載內核模塊時會調用的初始化函數。函數原型必須是module_init(),括號內是函數指針
  • 模塊析構函數:
    •   執行rmmod指令卸載模塊時調用的函數。函數原型是module_exit()
  • 模塊許可聲明:
    •   函數原型是MODULE_LICENSE(),告訴內核該程序使用的許可證,否則在加載時它會提示該模塊污染內核。通常會寫GPL。
  • 模塊參數(可選)
  • 模塊導出符號(可選)
  • 模塊做者信息聲明(可選)
  • 頭文件module.h,必須包含此文件;
  • 頭文件kernel.h,包含經常使用的內核函數;
  • 頭文件init.h包含宏_init和_exit,容許釋放內核佔用的內存。

 

寫一個代碼,用來遍歷內核全部進程。測試

 1 #include<linux/init.h>
 2 #include<linux/module.h>
 3 #include<linux/kernel.h>
 4 #include<linux/sched.h>
 5 
 6 
 7 static struct task_struct *pcurrent;
 8 int print_current_task_info(void);
 9 static int __init print_init(void)
10 {
11     
12     printk(KERN_INFO"print current task info\n");
13     printk("pid\ttgid\tprio\tstate\n");
14     for_each_process(pcurrent){
15         printk("%d\t",pcurrent->pid);
16         printk("%d\t",pcurrent->tgid);
17         printk("%d\t",pcurrent->prio);
18         printk("%ld\t",pcurrent->state);
19     }
20     return 0;
21 }
22 static void __exit print_exit(void)
23 {
24     printk(KERN_INFO"Module Finished!\n");
25 
26 }
27 
28 module_init(print_init);
29 module_exit(print_exit);

三、編譯模塊

接下來寫Makefile。spa

1 obj-m:=printname.o
2 CURRENT_PATH:=$(shell pwd)
3 LINUX_KERNEL_PATH:=/usr/src/linux-headers-3.16.0-70-generic
4 all:
5     make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
6 clean:
7     make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean

第一行的printname換成你本身寫的.c文件名(我用的a,別用會和其餘內核有衝突的名字)。3d

第二行表示獲取當前路徑。指針

第三行的LINUX_KERNEL_PATH後面要寫你本身的內核版本對應的內核源碼包地址,能夠用uname -a查看。code

解釋一下make命令:blog

make -C $(LINUX_KERNEL_PATH) 指明跳轉到內核源碼目錄下讀取那裏的Makefile進程

M=$(CURRENT_PATH) 代表返回到當前目錄繼續執行當前的Makefile。

 

make以後的執行時這樣的:

四、加載模塊

sudo insmod printname.ko

五、測試模塊

dmesg | tail 看內核信息

tail是查看尾部

六、卸載模塊

sudo rmmod printname

七、清除編譯的文件

相關文章
相關標籤/搜索