生活随笔
收集整理的這篇文章主要介紹了
driver: linux2.6 内核模块导出函数实例(EXPORT_SYMBOL)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
內(nèi)核版本:2.6.38-11-generic
????內(nèi)核自己都大量利用內(nèi)核符號(hào)表導(dǎo)出函數(shù),那么應(yīng)該導(dǎo)出呢,ldd3上面說(shuō)只需要EXPORT_SYMBOL一類(lèi)的宏導(dǎo)出即可,結(jié)果試了很久都不行,最后查看文檔,算是明白一點(diǎn)了。
????對(duì)于導(dǎo)出符號(hào)表,內(nèi)核文檔給出了三種解決方案,見(jiàn)尾部,現(xiàn)在忽略。
????現(xiàn)在有兩個(gè)模塊,a模塊導(dǎo)出函數(shù)myprint,b模塊使用該函數(shù),想象一下如果a模塊 EXPORT_SYMBOL(myprint) ,實(shí)際上b模塊知道嗎,很明顯b模塊對(duì)這件事情不是很清楚(這么說(shuō)不是很準(zhǔn)確),要調(diào)用a模塊的myprint函數(shù),需要知道m(xù)yprint函數(shù)在內(nèi)存中的位置,首先在內(nèi)核符號(hào)表中是沒(méi)有說(shuō)明的,所以...
????當(dāng)我們編譯完a模塊后,看看有些什么文件,是不是有一個(gè)Module.symvers文件,打開(kāi)看看什么狀況?
0x705034f7????myprint????/home/darren/Desktop/darren/print/myprint????EXPORT_SYMBOL
好了,這一行對(duì)b模塊來(lái)說(shuō)已經(jīng)足夠了,指定了內(nèi)存位置,符號(hào)名稱(chēng),模塊路徑。最簡(jiǎn)單的方法就是把這個(gè)文件復(fù)制到b模塊所在目錄,然后編譯就沒(méi)有討厭的錯(cuò)誤了,可以正常insmod模塊。這種方法是內(nèi)核文檔中提到的方法之一。
????但是每次調(diào)用該函數(shù)都要復(fù)制一次,更糟糕的是a模塊每編譯一次,都要重新復(fù)制一次,為什么內(nèi)核自己導(dǎo)出的函數(shù)我們可以直接用呢?現(xiàn)在就就解決:
????編譯內(nèi)核的時(shí)候同樣會(huì)生成一個(gè)Module.symvers文件,內(nèi)核導(dǎo)出的所有符號(hào)都在里面,我們?cè)诰幾g模塊的時(shí)候?qū)嶋H上會(huì)調(diào)用內(nèi)核的頂層makefile,也就是說(shuō)內(nèi)核的Module.symvers對(duì)我們的模塊是可見(jiàn)的,和我們自己的Module.symvers文件一樣,OK,把a(bǔ)模塊的Module.symvers文件合并到內(nèi)核的Module.symvers文件中,這時(shí)候myprint函數(shù)就成了真正的導(dǎo)出函數(shù)了,其他的模塊只需要生命一下就可以用了。
代碼如下
a模塊代碼:
點(diǎn)擊(此處)折疊或打開(kāi)
#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模塊代碼: 點(diǎn)擊(此處)折疊或打開(kāi)
#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如下: 點(diǎn)擊(此處)折疊或打開(kāi) 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: 點(diǎn)擊(此處)折疊或打開(kāi) 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 有可能不對(duì)如果不行就改成/usr/src/linux-headers-`uname -r`-generic/Module.symvers 內(nèi)核文檔: 點(diǎn)擊(此處)折疊或打開(kāi)
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 踩
總結(jié)
以上是生活随笔為你收集整理的driver: linux2.6 内核模块导出函数实例(EXPORT_SYMBOL)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。