一個(gè)簡(jiǎn)單的內(nèi)核模塊實(shí)現(xiàn)

一個(gè)簡(jiǎn)單的內(nèi)核模塊實(shí)現(xiàn)

前言

這幾天因?yàn)槟承┰颍枰獙W(xué)習(xí)下Linux內(nèi)核模塊相關(guān)的知識(shí)霸妹,今天剛剛好學(xué)習(xí)完模塊的簡(jiǎn)單實(shí)現(xiàn),故將其整理出來(lái),以供日后復(fù)習(xí)之用

一個(gè)簡(jiǎn)單的內(nèi)核模塊

模塊化的意義

在目前赊舶,內(nèi)核的設(shè)計(jì)中,有兩種不同的趨勢(shì)赶诊,一種是單內(nèi)核笼平,另外一種是微內(nèi)核,簡(jiǎn)單而言

  • 單內(nèi)核就是一個(gè)很大的進(jìn)程舔痪,在運(yùn)行的時(shí)候寓调,是一個(gè)單獨(dú)的二進(jìn)制映像,模塊之間的通信是通過(guò)函數(shù)調(diào)用來(lái)實(shí)現(xiàn)
  • 微內(nèi)核則不同锄码,各個(gè)模塊之間都作為單獨(dú)的進(jìn)程運(yùn)行夺英,模塊之間的通信是通過(guò)消息傳遞進(jìn)行通信

關(guān)于這兩者的優(yōu)勢(shì),各有各的說(shuō)法滋捶,本人研究也不深痛悯,無(wú)法做過(guò)多的點(diǎn)評(píng),這里我們只需要知道重窟,Linux是單內(nèi)核結(jié)構(gòu)载萌,但同時(shí)也支持一個(gè)模塊化的內(nèi)核。

所謂的模塊化,就是各個(gè)部分以模塊的形式進(jìn)行組織扭仁,可以根據(jù)需要對(duì)指定的模塊進(jìn)行編譯垮衷,然后安裝到內(nèi)核中即可,這種實(shí)現(xiàn)方式的優(yōu)勢(shì)在于乖坠,不需要預(yù)先把一大堆的功能都編譯進(jìn)內(nèi)核搀突,尤其是各種驅(qū)動(dòng),眾所周知瓤帚,不同型號(hào)的硬件描姚,對(duì)應(yīng)的驅(qū)動(dòng)不同,而如果為了顧全所有的硬件戈次,而把所有的驅(qū)動(dòng)都編譯進(jìn)內(nèi)核轩勘,內(nèi)核的體積會(huì)變得非常龐大,而且怯邪,當(dāng)這些驅(qū)動(dòng)需要進(jìn)行更新的時(shí)候绊寻,必須要對(duì)內(nèi)核重新進(jìn)行編譯。

有了模塊化之后悬秉,可以根據(jù)需要將對(duì)應(yīng)的模塊編譯進(jìn)內(nèi)核澄步,并且可以動(dòng)態(tài)的進(jìn)行加載和卸載,這樣子和泌,對(duì)應(yīng)的模塊的維護(hù)以及系統(tǒng)的使用就簡(jiǎn)單以及方便很多了

模塊的簡(jiǎn)單實(shí)現(xiàn)

這里我們來(lái)學(xué)習(xí)一個(gè)簡(jiǎn)單模塊的實(shí)現(xiàn)

// hello_module.c

// 必備頭函數(shù)
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>

// 該模塊的LICENSE
MODULE_LICENSE("GPL")村缸;
// 該模塊的作者
MODULE_AUTHOR("huanfeng.xu");
// 該模塊的說(shuō)明
MODULE_DESCRIPTION("hello module");

// 初始化入口
// 模塊安裝時(shí)執(zhí)行
// 這里的__init 同樣是宏定義,主要的目的在于
// 高速內(nèi)核武氓,加載該模塊之后梯皿,可以回收init.text的區(qū)間
static int __init init_hello_module(void){
    printk("KERN_INFO init the module. \n");
    return 0;
}

// 模塊卸載時(shí)執(zhí)行
// 同上
static void __exit exit_hello_module(void){
    // 輸出信息,類似于printf()
    // printk適用于內(nèi)核模塊
    printk("KERN_INFO exit the module. \n");
}

// 模塊初始化宏县恕,用于加載該模塊
module_init(init_hello_module);
// 模塊卸載宏东羹,用于卸載該模塊
module_exit(exit_hello_module);

需要注意的是,在普通的c開發(fā)中忠烛,每個(gè)程序都有一個(gè)main函數(shù)属提,作為入口,而在內(nèi)核中美尸,則是module_init()來(lái)負(fù)責(zé)

編寫對(duì)應(yīng)的Makefile


# Makefile

# 內(nèi)核源代碼所在位置
KERNEL_DIR = /lib/modules/`uname -r`/build

obj-m += hello_module.o

all:
    make -C $(KERNEL_DIR) M=$(PWD) modules

clean:
    rm *.o *.mod.c *.ko *.order *.symvers

模塊的編譯有兩種形式冤议,一種是編譯成模塊,即上面的obj-m师坎,另一中是直接編譯到內(nèi)核文件中恕酸,則上面的obj-m需要更改為obj-y

需要注意的是,由于我們是在內(nèi)核源代碼之外編譯該模塊屹耐,所以在編譯的時(shí)候尸疆,需要暫時(shí)將編譯目錄切換到內(nèi)核源代碼中,即上面的-C $(KERNEL_DIR)惶岭,在Makefile中寿弱,可以聲明變量,即上面的KERNEL_DIR = /lib/modules/uname -r/build按灶,使用時(shí)症革,直接$(KERNEL_DIR)即可,這里的$(PWD)是內(nèi)核自帶變量鸯旁,所以無(wú)需聲明噪矛,可以直接使用

編寫完之后,直接執(zhí)行make即可铺罢,可以看到目錄下生成一個(gè).ko文件艇挨,這就行對(duì)應(yīng)的模塊了

模塊的安裝

由于該模塊比較簡(jiǎn)單,也沒(méi)有依賴于其他模塊韭赘,所以安裝的時(shí)候可以直接使用insmod hello_module.ko即可缩滨,安裝完成之后,可以使用dmesg查看是否有對(duì)應(yīng)的內(nèi)容輸出泉瞻,如果操作沒(méi)有問(wèn)題脉漏,則會(huì)看到這樣的日志KERN_INFO init the module.

查看模塊是否已經(jīng)安裝 lsmod | grep hello_module

查看模塊信息 modinfo hello_module

卸載模塊 rmmod hello_module,卸載之后同樣可以使用dmesg看到
KERN_INFO exit the module.

帶參數(shù)的模塊

有時(shí)候我們需要在模塊安裝的時(shí)候袖牙,傳遞一些信息給模塊侧巨,可以使用如下方式


// 需要加上該頭文件
#include <linux/moduleparam.h>

module_param(name, type, perm);
// name為安裝以及使用時(shí)的參數(shù)名字,type為類型鞭达,pram為對(duì)應(yīng)的sysfs的權(quán)限

module_param_string(name, string, len, perm);
// name為外部名字司忱,string為內(nèi)部名字

module_param_array(name, type, nump, perm)
// nump用于存放數(shù)組項(xiàng)數(shù)

使用的方式為,在安裝模塊的指定對(duì)應(yīng)的參數(shù)及其值即可碉怔,如insmod hello_module size=100

導(dǎo)出符號(hào)表

由于模塊之間是相通的烘贴,所以模塊中定義的符號(hào)需要導(dǎo)出之后才能被其他模塊使用

導(dǎo)出方式只需要在使用EXPORT_SYMBOL(VAR_NAME)或者EXPORT_SYMBOL_GPL(VAR_NAME)即可,VAR_NAME可以為變量撮胧,也可以為函數(shù)

其他模塊只需要使用extern [TYPE] VAR_NAME桨踪,即可在本模塊中使用其他模塊導(dǎo)出的變量或者函數(shù)了,需要注意的是芹啥,如果依賴其他模塊的導(dǎo)出符號(hào)锻离,則在安裝該模塊的時(shí)候,對(duì)應(yīng)的依賴模塊必須已經(jīng)安裝好墓怀,否則會(huì)出現(xiàn)找不到對(duì)應(yīng)符號(hào)的情況

總結(jié)

本小節(jié)主要簡(jiǎn)單學(xué)習(xí)了模塊的寫法汽纠,模塊的編譯,傳遞參數(shù)以及導(dǎo)出符號(hào)傀履,后面還會(huì)學(xué)習(xí)其他相關(guān)的內(nèi)容虱朵,加油...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子碴犬,更是在濱河造成了極大的恐慌絮宁,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件服协,死亡現(xiàn)場(chǎng)離奇詭異绍昂,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)偿荷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門窘游,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人跳纳,你說(shuō)我怎么就攤上這事忍饰。” “怎么了寺庄?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵喘批,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我铣揉,道長(zhǎng)饶深,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任逛拱,我火速辦了婚禮敌厘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘朽合。我一直安慰自己俱两,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布曹步。 她就那樣靜靜地躺著宪彩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪讲婚。 梳的紋絲不亂的頭發(fā)上尿孔,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音筹麸,去河邊找鬼活合。 笑死,一個(gè)胖子當(dāng)著我的面吹牛物赶,可吹牛的內(nèi)容都是我干的白指。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼酵紫,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼告嘲!你這毒婦竟也來(lái)了错维?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤橄唬,失蹤者是張志新(化名)和其女友劉穎需五,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體轧坎,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年泽示,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了缸血。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡械筛,死狀恐怖捎泻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情埋哟,我是刑警寧澤笆豁,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站赤赊,受9級(jí)特大地震影響闯狱,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜抛计,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一哄孤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吹截,春花似錦瘦陈、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至懦铺,卻和暖如春捉貌,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背冬念。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工昏翰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人刘急。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓棚菊,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親叔汁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子统求,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,116評(píng)論 25 707
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理检碗,服務(wù)發(fā)現(xiàn),斷路器码邻,智...
    卡卡羅2017閱讀 134,656評(píng)論 18 139
  • 我們說(shuō)的Linux其實(shí)指的就是 內(nèi)核(kernel)而已折剃。這個(gè)內(nèi)核控制你主機(jī)的所有硬件并提供系統(tǒng)所有的功能,所以它...
    Zhang21閱讀 7,418評(píng)論 0 18
  • 一像屋、溫故而知新 1. 內(nèi)存不夠怎么辦 內(nèi)存簡(jiǎn)單分配策略的問(wèn)題地址空間不隔離內(nèi)存使用效率低程序運(yùn)行的地址不確定 關(guān)于...
    SeanCST閱讀 7,808評(píng)論 0 27
  • 作者:瑪利亞·杜埃尼亞斯 譯者:羅秀 文章以第一人稱的方式講的一個(gè)生長(zhǎng)在西班牙貧民區(qū)的從一個(gè)無(wú)知小裁縫希拉被命...
    嘉里閱讀 774評(píng)論 0 1