更多技術(shù)干貨內(nèi)容請(qǐng)穩(wěn)步到“電子發(fā)燒友網(wǎng)”公眾號(hào),回復(fù)資料即可免費(fèi)獲取一份技術(shù)資料,在這里每天可以獲取最專業(yè)、最前沿的電子技術(shù)。
Linux內(nèi)核是整體性結(jié)構(gòu),各個(gè)子系統(tǒng)緊密聯(lián)系,上接用戶控件,下接硬件,作為一個(gè)大程序在內(nèi)核控件運(yùn)行。
如果將所有的設(shè)備驅(qū)動(dòng)和內(nèi)核功能都集成在內(nèi)核中,則內(nèi)核會(huì)不斷的龐大,對(duì)我們的內(nèi)核裁剪也會(huì)帶來(lái)更大的挑戰(zhàn),為了解決這個(gè)問(wèn)題,Linux內(nèi)核引入內(nèi)核模塊機(jī)制,通過(guò)動(dòng)態(tài)加載內(nèi)核模塊,從而實(shí)現(xiàn)在運(yùn)行過(guò)程中擴(kuò)展內(nèi)核的功能。
內(nèi)核模塊是什么?
1 內(nèi)核模塊是一種沒(méi)有經(jīng)過(guò)鏈接,不能獨(dú)立運(yùn)行的目標(biāo)文件,是在內(nèi)核空間中運(yùn)行的程序。經(jīng)過(guò)鏈接裝載到內(nèi)核里面成為內(nèi)核的一部分,可以訪問(wèn)內(nèi)核的公用符號(hào)(函數(shù)和變量)。
2 內(nèi)核模塊可以讓操作系統(tǒng)內(nèi)核在需要時(shí)載入和執(zhí)行,在不需要時(shí)由操作系統(tǒng)卸載。它們擴(kuò)展了操作系統(tǒng)內(nèi)核的功能卻不需要重新啟動(dòng)系統(tǒng)。
3 如果沒(méi)有內(nèi)核模塊,我們不得不一次又一次重新編譯生成單內(nèi)核操作系統(tǒng)的內(nèi)核鏡像來(lái)加入新的功能。這還意味著一個(gè)臃腫的內(nèi)核。
模塊機(jī)制的優(yōu)點(diǎn):
1 減小內(nèi)核映像尺寸,增加系統(tǒng)靈活性;
2 節(jié)省開(kāi)發(fā)時(shí)間;修改內(nèi)核,不必重新編譯整個(gè)內(nèi)核。
3 模塊的目標(biāo)代碼一旦被鏈入內(nèi)核,作用和靜態(tài)鏈接的內(nèi)核目標(biāo)代碼完全等價(jià)。
模塊機(jī)制的缺點(diǎn):
1 對(duì)系統(tǒng)性能有一定損失;
2 使用不當(dāng)時(shí)會(huì)導(dǎo)致系統(tǒng)崩潰;
接下來(lái)通過(guò)
首先先附上模塊的代碼(hello_world.c)
1 #include
2 #include
3 #include
4
5 static int hello_init(void)
6 {
7 printk("hello world module! ");
8 return 0;
9 }
10
11 static void hello_exit(void)
12 {
13 printk("good bye module! ");
14 }
15
16 module_init(hello_init);
17 module_exit(hello_exit);
18
19 MODULE_LICENSE("GPL");
內(nèi)核模塊至少包含兩個(gè)函數(shù):
入口函數(shù)->初始化函數(shù)(xxx_init()):模塊加載時(shí),被調(diào)用
出口函數(shù)->卸載函數(shù)(xxx_exit()):模塊卸載時(shí),被調(diào)用
模塊的入口函數(shù)名和出口函數(shù)名可以任意命名,通過(guò)宏module_init()申明入口函數(shù),通過(guò)宏module_exit()申明出口函數(shù)。模塊需要包含頭文件:#include
內(nèi)核模塊證書:2.4內(nèi)核后,引入識(shí)別代碼是否在GPL許可下發(fā)布的機(jī)制 。在使用非公開(kāi)的源代碼產(chǎn)品時(shí)會(huì)得到警告。通過(guò)宏MODULE_LICENSE(“GPL”),設(shè)置模塊遵守GPL證書,取消警告信息。
內(nèi)核模塊的構(gòu)建:
管理模塊源碼方法: ① 模塊源碼加入到內(nèi)核源碼樹中。② 模塊源碼飯仔內(nèi)核源碼樹之外。
注:本文介紹的是放在內(nèi)核源碼樹外編譯。
接下來(lái)是Makefile的實(shí)現(xiàn):
首先附上Makefile的源碼
1 KERNEL_DIR = /home/FAN/linux-kernel
2
3 all:
4 make -C $(KERNEL_DIR) M=`pwd` modules
5 clean:
6 make -C $(KERNEL_DIR) M=`pwd` modules clean
7 rm -rf modules.order Module.symvers
8
9 obj-m += hello_world.o
其中:
1、KERNEL_DIR:參數(shù),賦值內(nèi)核的位置,例如我的內(nèi)核源碼的路徑:/home/fan/linux-kernrl
2、當(dāng)終端執(zhí)行make時(shí),會(huì)運(yùn)行make -C $(KERNEL_DIR) M=`pwd` modules,其中M=`pwd`指向是模塊所在的路徑。
3、當(dāng)終端執(zhí)行make clean時(shí),會(huì)運(yùn)行下面兩條命令,將編譯生成的文件刪除
make -C $(KERNEL_DIR) M=`pwd` modules clean
rm -rf modules.order Module.symvers
4、obj-m += hello_world.o:其中 –m 表示將hello_world.c編譯成模塊
–y 表示將hello_world.c編譯進(jìn)內(nèi)核鏡像中
編譯生成文件:
在終端運(yùn)行make,則會(huì)生成hello_world.ko文件.
將hello_world.ko發(fā)送到板子上,然后在板子上運(yùn)行insmod hello_world.ko, 會(huì)調(diào)用hello_init()函數(shù)運(yùn)行rmmod hello_world.ko,會(huì)調(diào)用hello_exit()函數(shù)
下圖為運(yùn)行結(jié)果:
本文作者:飯仔DIY,工作之余喜歡電子DIY,開(kāi)源分享是我寫文章的動(dòng)力,互相學(xué)習(xí)才能讓自己不斷強(qiáng)大。
歡迎廣大電子發(fā)燒友們投稿,投稿郵箱:liuyong@elecfans.com
-
Linux
+關(guān)注
關(guān)注
87文章
11304瀏覽量
209535
原文標(biāo)題:【原創(chuàng)】linux 了解內(nèi)核模塊的原理 《Rice linux 學(xué)習(xí)開(kāi)發(fā)》
文章出處:【微信號(hào):elecfans,微信公眾號(hào):電子發(fā)燒友網(wǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論