driver: linux2.6 核心模組匯出函數執行個體(EXPORT_SYMBOL) 【轉】

來源:互聯網
上載者:User

標籤:

轉自:http://blog.chinaunix.net/uid-23381466-id-3837650.html

核心版本:2.6.38-11-generic

    核心自己都大量利用核心符號表匯出函數,那麼應該匯出呢,ldd3上面說只需要EXPORT_SYMBOL一類的宏匯出即可,結果試了很久都不行,最後查看文檔,算是明白一點了。

    對於匯出符號表,核心文檔給出了三種解決方案,見尾部,現在忽略。

    現在有兩個模組,a模組匯出函數myprint,b模組使用該函數,想象一下如果a模組 EXPORT_SYMBOL(myprint) ,實際上b模組知道嗎,很明顯b模組對這件事情不是很清楚(這麼說不是很準確),要調用a模組的myprint函數,需要知道myprint函數在記憶體中的位置,首先在核心符號表中是沒有說明的,所以...

    當我們編譯完a模組後,看看有些什麼檔案,是不是有一個Module.symvers檔案,開啟看看什麼狀況?
0x705034f7    myprint    /home/darren/Desktop/darren/print/myprint    EXPORT_SYMBOL
好了,這一行對b模組來說已經足夠了,指定了記憶體位置,符號名稱,模組路徑。最簡單的方法就是把這個檔案複製到b模組所在目錄,然後編譯就沒有討厭的錯誤了,可以正常insmod模組。這種方法是核心文檔中提到的方法之一。

    但是每次調用該函數都要複製一次,更糟糕的是a模組每編譯一次,都要重新複製一次,為什麼核心自己匯出的函數我們可以直接用呢?現在就就解決:

    編譯核心的時候同樣會產生一個Module.symvers檔案,核心匯出的所有符號都在裡面,我們在編譯模組的時候實際上會調用核心的頂層makefile,也就是說核心的Module.symvers對我們的模組是可見的,和我們自己的Module.symvers檔案一樣,OK,把a模組的Module.symvers檔案合并到核心的Module.symvers檔案中,這時候myprint函數就成了真正的匯出函數了,其他的模組只需要生命一下就可以用了。

代碼如下
a模組代碼

  1. #include <linux/module.h>
  2. #include <linux/init.h>
  3. #include <linux/kernel.h> 
  4. MODULE_LICENSE("GPL");
  5. int myprint(void)
  6. {
  7.     printk("c");
  8.     return 0;
  9. }
  10. static int darren_init(void)
  11. {
  12.     return 0;
  13. }
  14. static void darren_exit(void)
  15. {
  16. }
  17. module_init(darren_init);
  18. module_exit(darren_exit);
  19. EXPORT_SYMBOL(myprint);

b模組代碼

  1. #include <linux/seq_file.h>
  2. #include <linux/cdev.h>
  3. #include <asm/system.h> 
  4. MODULE_LICENSE("GPL");
  5. extern int print(void);
  6. static int darren_init(void)
  7. {
  8.     int i=0;
  9.     printk("b module init\n");
  10.     for(;i<10;i++)print();
  11.     return 0;
  12. }
  13. static void darren_exit(void)
  14. {
  15. }
  16. module_init(darren_init);
  17. module_exit(darren_exit);

a模組的Makefile如下:

  1. NAME:=a
  2. SYM:=/usr/src/linux-headers-2.6.38-8-generic/Module.symvers
  3. DIR:=/lib/modules/$(shell uname -r)/build/
  4. PWD:=$(shell pwd)
  5. obj-m = $(NAME).o
  6. build: 
  7.     
  8.     make -C $(DIR) M=$(PWD)
  9.     sudo chmod 777 $(SYM)
  10.     sudo sed -i ‘/myprint/d‘ $(SYM)
  11.     sudo cat Module.symvers>>$(SYM)
  12.     sudo chmod 644 $(SYM)


b模組的makefile:

  1. NAME:=b
  2. DIR:=/lib/modules/$(shell uname -r)/build/
  3. PWD:=$(shell pwd)
  4. obj-m = $(NAME).o
  5. build: 
  6.     make -C $(DIR) M=$(PWD)


注意:路徑/usr/src/linux-headers-2.6.38-8-generic/Module.symvers 有可能不對如果不行就改成/usr/src/linux-headers-`uname -r`-generic/Module.symvers

核心文檔:

  1. Sometimes, an external module uses exported symbols from
  2.     another external module. kbuild needs to have full knowledge of
  3.     all symbols to avoid spitting out warnings about undefined
  4.     symbols. Three solutions exist for this situation.
  5.     NOTE: The method with a top-level kbuild file is recommended
  6.     but may be impractical in certain situations.
  7.     Use a top-level kbuild file
  8.         If you have two modules, foo.ko and bar.ko, where
  9.         foo.ko needs symbols from bar.ko, you can use a
  10.         common top-level kbuild file so both modules are
  11.         compiled in the same build. Consider the following
  12.         directory layout:
  13.         ./foo/ <= contains foo.ko
  14.         ./bar/ <= contains bar.ko
  15.         The top-level kbuild file would then look like:
  16.         #./Kbuild (or ./Makefile):
  17.             obj-y := foo/ bar/
  18.         And executing
  19.             $ make -C $KDIR M=$PWD
  20.         will then do the expected and compile both modules with
  21.         full knowledge of symbols from either module.
  22.     Use an extra Module.symvers file
  23.         When an external module is built, a Module.symvers file
  24.         is generated containing all exported symbols which are
  25.         not defined in the kernel. To get access to symbols
  26.         from bar.ko, copy the Module.symvers file from the
  27.         compilation of bar.ko to the directory where foo.ko is
  28.         built. During the module build, kbuild will read the
  29.         Module.symvers file in the directory of the external
  30.         module, and when the build is finished, a new
  31.         Module.symvers file is created containing the sum of
  32.         all symbols defined and not part of the kernel.
  33.     Use "make" variable KBUILD_EXTRA_SYMBOLS
  34.         If it is impractical to copy Module.symvers from
  35.         another module, you can assign a space separated list
  36.         of files to KBUILD_EXTRA_SYMBOLS in your build file.
  37.         These files will be loaded by modpost during the
  38.         initialization of its symbol tables.

driver: linux2.6 核心模組匯出函數執行個體(EXPORT_SYMBOL) 【轉】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.