內核模塊編程
1、準備工做
虛擬機:VMware Workstation 12
操做系統:ubuntu
當前內核版本:linux-headers-4.4.0-22-genericlinux
2、有關於內核模塊的知識
模塊是具備獨立功能的程序,它能夠被單獨編譯,但不能獨立運行。它在運行時被連接到內核做爲內核的一部分在內核空間運行,這與運行在用戶空間的進程是不一樣的。模塊一般由一組函數和數據結構組成,用來實現一種文件系統、一個驅動程序或其餘內核上層的功能。shell
內核模塊的相關指令:編程
查看內核版本ubuntu
uname –a
模塊編譯好後,將模塊放入內核數據結構
insmod 1.ko
查看程序的輸出函數
dmesg
卸載模塊spa
rmmod 1
3、編譯造成新內核操作系統
根據學姐的代碼:code
Makefileblog
1 obj-m:=1.o 2 CURRENT_PATH:=$(shell pwd) 3 LINUX_KERNEL_PATH:=/usr/src/linux-headers-4.4.0-22-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
第1行:產生1模塊的目標模塊
第2行:模塊所在的當前路徑
第3行:LINUX_KERNEL_PATH後面要寫你本身的內核版本對應的內核源碼包地址。
make-C $(LINUX_KERNEL_PATH) 指明跳轉到內核源碼目錄下讀取那裏的Makefile,M=$(CURRENT_PATH) 代表返回到當前目錄繼續執行當前的Makefile。
第5行:模塊編譯
第7行:清理
1.c
1 #include <linux/kernel.h> 2 #include <linux/module.h> 3 #include <linux/init.h> 4 #include <linux/sched.h> 5 6 static struct task_struct *pcurrent; 7 static int __init print_init(void) 8 { 9 printk(KERN_INFO "print current task info\n"); 10 printk("pid\ttgid\tprio\tstate\n"); 11 for_each_process(pcurrent){ 12 printk("%d\t",pcurrent->pid); 13 printk("%d\t",pcurrent->tgid); 14 printk("%d\t",pcurrent->prio); 15 printk("%ld\n",pcurrent->state); 16 } 17 return 0; 18 } 19 20 static void __exit print_exit(void) 21 { 22 printk(KERN_INFO "Finished\n"); 23 } 24 module_init(print_init); 25 module_exit(print_exit);
第1行:linux/kernel.h包含了經常使用的內核函數。
第2行:linux/module.h是必要的頭文件,內核模塊代碼中必須包含。
第3行:linux/init.h含了宏_init和_exit,它們容許釋放內核佔用的內存。
第12行:Printk的功能相似於C語言中的printf,這個函數是由內核定義的。
先make生成1.ko文件等,在insmod 1.ko將模塊放入內核,最後dmesg查看所編譯程序的輸出
4、遇到問題
在make這一步所遇到的基本全部問題都是由於.c文件出錯所形成的。
還有一個問題就是在以前加載過模塊以後再進行加載時會出現錯誤,這時將模塊卸載了再進行加載就能夠了。