一個模塊mod1中定義一個函數func1;在另外一個模塊mod2中定義一個函數func2,func2調用func1。
在模塊mod1中,EXPORT_SYMBOL(func1);
在模塊mod2中,extern int func1();
就可以在mod2中調用func1了。
同理EXPORT_SYMBOL_GPL使用
=================================
EXPORT_SYMBOL只出現在2.6內核中,在2.4內核默認的非static 函數和變量都會自動導入到kernel 空間的, 都不用EXPORT_SYMBOL() 做標記的。
2.6就必須用EXPORT_SYMBOL() 來導出來(因為2.6默認不到處所有的符號)。
1、EXPORT_SYMBOL的作用是什么?
EXPORT_SYMBOL標簽內定義的函數或者符號對全部內核代碼公開,不用修改內核代碼就可以在您的內核模塊中直接調用,即使用EXPORT_SYMBOL可以將一個函數以符號的方式導出給其他模塊使用。
這里要和System.map做一下對比:
System.map 中的是連接時的函數地址。連接完成以后,在2.6內核運行過程中,是不知道哪個符號在哪個地址的。
EXPORT_SYMBOL的符號,是把這些符號和對應的地址保存起來,在內核運行的過程中,可以找到這些符號對應的地址。而模塊在加載過程中,其本質就是能動態連接到內核,如果在模塊中引用了內核或其它模塊的符號,就要EXPORT_SYMBOL這些符號,這樣才能找到對應的地址連接。
2、使用方法
第一、在模塊函數定義之后使用EXPORT_SYMBOL(函數名)
第二、在掉用該函數的模塊中使用extern對之聲明
第三、首先加載定義該函數的模塊,再加載調用該函數的模塊
另外,在編譯調用某導出函數的模塊時,往往會有WARNING: "****" [**********] undefined!
使用dmesg命令后會看到相同的信息。開始我以為只要有這個錯誤就不能加載模塊,后來上網查了一下,發現這主要是因為在編譯連接的時候還沒有和內核打交道,當然找不到symbol了,但是由於你生成的是一個內核模塊,所以LD不提示error,而是給出一個warning,寄希望於在insmod的時候,內核能夠把這個symbol連接上。
Linux內核頭文件提供了一個方便的方法用來管理符號的對模塊外部的可見性,因此減少了命名空間的污染(命名空間的名稱可能會與內核其他地方定義的名稱沖突),並且適當信息隱藏。 如果你的模塊需要輸出符號給其他模塊使用,應當使用下面的宏定義:
EXPORT_SYMBOL(name);
EXPORT_SYMBOL_GPL(name);
這兩個宏均用於將給定的符號導出到模塊外. _GPL版本的宏定義只能使符號對GPL許可的模塊可用。 符號必須在模塊文件的全局部分導出,不能在函數中導出,這是因為上述這兩個宏將被擴展成一個特殊用途的聲明,而該變量必須是全局的。這個變量存儲於模塊的一個特殊的可執行部分(一個"ELF段" ),在裝載時,內核通過這個段來尋找模塊導出的變量(感興趣的讀者可以看<linux/module.h>獲知更詳細的信息)。
————————————————
版權聲明:本文為CSDN博主「王牧天」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/wangweiqiang1325/article/details/51569473