17 驅動模組的符號匯出(一個驅動模組呼叫另一個驅動模組)
阿新 • • 發佈:2018-11-25
驅動模組的符號匯出(一個驅動模組呼叫另一個驅動模組)
檢視elf檔案的資訊 :
readelf xxx.ko -a
UND標識的函式在核心符號表裡都是“T”,表示是全域性函式,也就是說只有全域性函式,核心才會幫我們把相應的函式地址轉換好
驅動模組裡預設情況下不管是函式還是全域性變數都是作區域性使用(相當於在函式或者變數名前加了“static”)
如果需要作為全域性使用,需要使用匯出符號“EXPORT_SYMBOL(函式名或者變數)”,來宣告函式或者變數為全域性使用,提供給其它驅動模組呼叫
實現一個核心裡的全域性函式“funca”,在其它驅動模組裡呼叫(myfunc.c):
#include <linux/init.h>
#include <linux/module.h>
void funca(char *str)
{
printk("In funca : %s\n", str);
}
EXPORT_SYMBOL(funca);//將funca釋出為核心裡的全域性函式,在其它驅動模組裡呼叫
MODULE_LICENSE("GPL");
呼叫funca函式的mytest模組(mytest.c):
#include <linux/module.h>
#include <linux/init.h>
extern void funca(char *str);//外部宣告
void funcb(char *str)
{
printk("In %s : %s\n", __func__, str);
}
static int __init test_init(void)
{
printk("This is the init func\n");
funca("the aaaaaa");//呼叫外部全域性函式
funcb("the bbbbbb");//呼叫自己的函式
printk("init\n");
return 0;
}
static void __exit test_exit(void )
{
printk("exit\n");
}
module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
Makefile檔案(生成兩個.ko檔案):
obj-m += mytest.o
obj-m += myfunc.o
#linux原始碼編譯路勁
KSRC := /目錄路徑/orangepi_sdk/source/linux-3.4.112/
#指定架構
export ARCH := arm
#指定編譯器(交叉編譯器)
export CROSS_COMPILE := arm-linux-gnueabihf-
all :
make -C $(KSRC) modules M=`pwd`
.PHONY : clean
clean :
make -C $(KSRC) modules clean M=`pwd`
Makefile檔案(只生成一個.ko檔案):
#通過test.o(不能與包含的任何一個.o檔案同名)來生成test.ko(只生成一個.ko)
obj-m += test.o
#指定test.o中包含mytest.o和myfunc.o
test-objs := mytest.o myfunc.o
#linux原始碼編譯路勁
KSRC := /home/sunwin/Desktop/orangepi_sdk/source/linux-3.4.112/
#指定架構
export ARCH := arm
#指定編譯器(交叉編譯器)
export CROSS_COMPILE := arm-linux-gnueabihf-
all :
make -C $(KSRC) modules M=`pwd`
.PHONY : clean
clean :
make -C $(KSRC) modules clean M=`pwd`
用生成兩個.ko的Makefile編譯後,載入和解除安裝mytest驅動模組時都會呼叫到myfunc裡的funca函式。
載入驅動模組的順序,如果myfunc驅動模組不先載入,則mytest模組會載入不成功。
解除安裝myfunc模組驅動時要先解除安裝myfunc模組,要是先解除安裝myfunc模組,因為myfunc裡的函式被mytest模組呼叫,會導致解除安裝不了。
insmod myfunc.ko
insmod mytest.ko
rmmod mytest
rmmod myfunc
用生成一個.ko的Makefile編譯後,載入和解除安裝test驅動模組時會呼叫myfunc裡的funca函式。
insmod test.ko
rmmod test
編譯載入模組後,可以在核心符號表裡檢視到驅動模組裡的函式:
cat /proc/kallsyms | grep 函式名