linux內核模塊之間通信
今天師兄問,linux內核模塊之間如何進行通信?我纔想起我之前也有這個疑問,只是當時不需要所以就沒去關心了。晚上查了些資料,終於弄明白了些。
這裏的通信可以簡單點理解,就是模塊B如何調用A的函數,變量或者常量。爲了簡化,我設計一個模塊A中的一個函數爲printMSG,原型爲int printMSG(int n);傳入的參數n表示打印幾遍一個固定的字符串。模塊A(在helloworld基礎上修改的,所以名字都沒變…懶)源碼:
#include <linux/init.h> #include <linux/module.h> int __init hello_init(void){ printk(KERN_ALERT "hello world "); return 0; } int printMSG(int n){ int i; for(i=0;i<n;i++) printk(KERN_ALERT "I am boluor "); return 0; } void __exit hello_exit(void){ printk(KERN_ALERT "byebye,hello world "); } EXPORT_SYMBOL(printMSG); module_init(hello_init); module_exit(hello_exit);
其中用到了EXPORT_SYMBOL宏來表明導出printMSG這個符號。還有一個EXPORT_SYMBOL_GPL宏,導出的符號具有GPL授權。內核所有的導出符號可以通過 : cat /proc/kallsyms來查看,太多了,所以最好導出到一個文件中慢慢看。在其中就可以發現printk等等我們常見的內核函數。
現在我們寫一個測試模塊B,他將調用A中的printMSG函數。B的源碼和A大致一樣,這裏只給出不同的地方吧。
extern int printMSG(int n); //聲明printMSG來自外部文件. int __init test_init(void){ //在模塊加載的時候調用. printk(KERN_ALERT "hello world "); printMSG(3); return 0; }
兩個模塊的Makefile文件參照Linux設備驅動學習筆記.編譯通過後,先insmod 模塊A,再insmod B,就可以發現B可以插入了。查看log,通過dmesg | tail -10就可以發現B在加載的時候輸出了三行”I am boluor”。
通過以上的測試,對linux所謂的LKM有了更深的認識。內核其實就是一個大的程序,當我們動態的加載進入一個模塊時,他還是內核這個大程序的一部分,所以我們可以像一個工程中那樣,將函數導出到內核符號表中,再將需要調用的外部的函數聲明爲extern關鍵字,就可以方便的調用了。
從回來到現在,搜了很多資料,抄來抄去的,都沒說明到底怎麼作,問題依舊沒有答案。在CSDN上看到一帖,也說得這問題,中有人說,需要使用系統調用。。。不知道怎麼想的,反正測試沒通過。這些還是得靠不斷的去試,纔會有正確的結果。
看完了^.^,如果覺得這篇文章對你有用或者有問題,請留言告訴我,thank you !
文章爲原創的話,轉載請註明出處.不敢流淚-《linux內核模塊之間通信》