Linux模塊間通訊方法非常的多,最便捷的方法莫過於函數符號導出,然後直接調用。然而在linux2.6.26以後的內核中模塊的符號導出經常會出現問題,一個模塊中的導出符號不能被另外一個模塊進行調用。這個使得處理有依賴關系的模塊非常的頭疼。
1. 符號導出函數
EXPORT_SYMBOL()
EXPORT_SYMBOL標簽內定義的函數對全部內核代碼公開,不用修改內核代碼就可以在您的內核模塊中直接調用。
EXPORT_SYMBOL_GPL()
EXPORT_SYMBOL_GPL和前面一個類似,但這個范圍只適合GPL許可的模塊進行調用。
2. 使用方法
加入B中調用A中導出函數
[1] 在模塊A中c文件或者頭文件中使用EXPORT_SYMBOL(xxxx)導出函數.
有些需要添加編譯選項-DEXPORT_SYMTAB.
[2] 在模塊B中用"extern" 申明函數(如, extern int xxxx);
申明以後就能夠直接使用導出的函數了。
另外:在導出函數以後,可以使用 cat proc/kallsyms來查看所有的導出符號,其中屬性為t的標識是不能被調用的,所以如果導出符號是t類型,那麼無法直接被其他模塊使用。
3. 無法導出問題解決
方法一:在A模塊編譯好後會生成符號表文件Module_symvers,裡面有函數地址和函數名對應關系,把這個文件拷貝到需要調用的B的源代碼下,替換B的該文件。
然後重新編譯B模塊.這樣就能夠讓B調用A的函數,以後加載模塊順序也必須先A後B,卸載相反。
方法二:將兩個模塊放在一個目錄下,進行編譯。其實和方法一類似。
這樣就能夠成功的實現兩個模塊之間的函數調用,比如KVM如果需要和驅動模塊相互調用,就能使用這個方法。如果是兩個模塊之間需要相互調用,可以讓驅動模塊函數導出,KVM模塊將函數指針當做回調函數傳給驅動,是想雙方的函數調用通訊。
記得這個問題出來以後一直沒有很好的解決,而且這個問題也許是一種系統的需要,而且Linux開發小組也沒有打算去處理這個問題。