《linux內核設計與分析》內核模塊編程


內核模塊編程

一、准備工作

虛擬機:VMware Workstation 12
操作系統:ubuntu
當前內核版本:linux-headers-4.4.0-22-generic

二、有關於內核模塊的知識

模塊是具有獨立功能的程序,它可以被單獨編譯,但不能獨立運行。它在運行時被鏈接到內核作為內核的一部分在內核空間運行,這與運行在用戶空間的進程是不同的。模塊通常由一組函數和數據結構組成,用來實現一種文件系統、一個驅動程序或其他內核上層的功能。

內核模塊的相關指令:

查看內核版本

uname –a

模塊編譯好后,將模塊放入內核

insmod 1.ko

查看程序的輸出

dmesg

卸載模塊

rmmod 1

 

三、編譯形成新內核

根據學姐的代碼:

Makefile

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查看所編譯程序的輸出

四、遇到問題

在make這一步所遇到的基本所有問題都是因為.c文件出錯所造成的。

還有一個問題就是在之前加載過模塊之后再進行加載時會出現錯誤,這時將模塊卸載了再進行加載就可以了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM