日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

driver: linux2.6 内核模块导出函数实例(EXPORT_SYMBOL)

發布時間:2025/3/21 linux 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 driver: linux2.6 内核模块导出函数实例(EXPORT_SYMBOL) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

內核版本: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模塊代碼

點擊(此處)折疊或打開

  • #include?<linux/module.h>
  • #include?<linux/init.h>
  • #include?<linux/kernel.h>?

  • MODULE_LICENSE("GPL");
  • int?myprint(void)
  • {
  • ????printk("c");
  • ????return 0;
  • }
  • static?int?darren_init(void)
  • {
  • ????return 0;
  • }
  • static void darren_exit(void)
  • {
  • }
  • module_init(darren_init);
  • module_exit(darren_exit);
  • EXPORT_SYMBOL(myprint);
  • b模塊代碼

    點擊(此處)折疊或打開

  • #include?<linux/seq_file.h>
  • #include?<linux/cdev.h>
  • #include?<asm/system.h>?

  • MODULE_LICENSE("GPL");
  • extern?int?print(void);
  • static?int?darren_init(void)
  • {
  • ????int?i=0;
  • ????printk("b module init\n");
  • ????for(;i<10;i++)print();
  • ????return 0;
  • }
  • static void darren_exit(void)
  • {
  • }
  • module_init(darren_init);
  • module_exit(darren_exit);
  • a模塊的Makefile如下:
    點擊(此處)折疊或打開
  • NAME:=a
  • SYM:=/usr/src/linux-headers-2.6.38-8-generic/Module.symvers
  • DIR:=/lib/modules/$(shell uname?-r)/build/
  • PWD:=$(shell pwd)
  • obj-m?=?$(NAME).o
  • build:?
  • ????
  • ????make?-C $(DIR)?M=$(PWD)
  • ????sudo chmod 777 $(SYM)
  • ????sudo sed?-i?'/myprint/d'?$(SYM)
  • ????sudo cat Module.symvers>>$(SYM)
  • ????sudo chmod 644 $(SYM)

  • b模塊的makefile:
    點擊(此處)折疊或打開
  • NAME:=b
  • DIR:=/lib/modules/$(shell uname?-r)/build/
  • PWD:=$(shell pwd)
  • obj-m?=?$(NAME).o
  • build:?
  • ????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

    內核文檔:

    點擊(此處)折疊或打開

  • Sometimes,?an external module?uses?exported symbols from
  • ????another external module.?kbuild needs to have full knowledge?of
  • ????all symbols to avoid spitting?out?warnings about undefined
  • ????symbols.?Three solutions exist?for?this?situation.

  • ????NOTE:?The method with a top-level kbuild file is recommended
  • ????but may be impractical?in?certain situations.

  • ????Use a top-level kbuild file
  • ????????If?you have two modules,?foo.ko?and?bar.ko,?where
  • ????????foo.ko needs symbols from bar.ko,?you can use a
  • ????????common top-level kbuild file so both modules are
  • ????????compiled?in?the same build.?Consider the following
  • ????????directory layout:

  • ????????./foo/?<=?contains foo.ko
  • ????????./bar/?<=?contains bar.ko

  • ????????The top-level kbuild file would then look like:

  • ????????#./Kbuild?(or?./Makefile):
  • ????????????obj-y?:=?foo/ bar/

  • ????????And?executing

  • ????????????$ make?-C $KDIR M=$PWD

  • ????????will then do the expected?and?compile both modules with
  • ????????full knowledge?of?symbols from either module.

  • ????Use an extra Module.symvers file
  • ????????When an external module is built,?a Module.symvers file
  • ????????is generated containing all exported symbols which are
  • ????????not?defined?in?the kernel.?To get access to symbols
  • ????????from bar.ko,?copy the Module.symvers file from the
  • ????????compilation?of?bar.ko to the directory where foo.ko is
  • ????????built.?During the module build,?kbuild will read the
  • ????????Module.symvers file?in?the directory?of?the external
  • ????????module,?and?when the build is finished,?a new
  • ????????Module.symvers file is created containing the sum?of
  • ????????all symbols defined?and?not?part?of?the kernel.

  • ????Use?"make"?variable KBUILD_EXTRA_SYMBOLS
  • ????????If?it is impractical to copy Module.symvers from
  • ????????another module,?you can assign a space separated list
  • ????????of?files to KBUILD_EXTRA_SYMBOLS?in?your build file.
  • ????????These files will be loaded by modpost during the
  • ????????initialization?of?its symbol tables.
  • 0

    總結

    以上是生活随笔為你收集整理的driver: linux2.6 内核模块导出函数实例(EXPORT_SYMBOL)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。