EXPORT_SYMBOL標籤內定義的函數或者符號對全部核心代碼公開,不用修改核心代碼就可以在您的核心模組中直接調用,即使用
EXPORT_SYMBOL可以將一個函數以符號的方式匯出給其他模組使用
。
您還可以手工修改核心原始碼來匯出另外的函數,用於重新編譯並載入新核心後的測試。
Linux symbol export method:
[1] If we want export the symbol in a module, just use the EXPORT_SYMBOL(xxxx
)
in the C or H file.
And compile the module by adding the compile flag -DEXPORT_SYMTAB
.
Then we can use the xxxx
in the other module.
[2] If we want export some symbol in Kernel that is not in a module such as xxxx
in the /arch/ppc/fec.c
.
Firstly, define the
xxxx
in the fec.c
;
Secondly, make a new file which contain the "extern"
define the
xxxx
(for example, extern int
xxxx
);
Lastly, in the ppc_ksyms.c
we includes the new file, and add the EXPORT_SYMBOL
(
xxxx
).
Then we can use the
xxxx
.
使用時注意事項:
在使用EXPORT_SYMBOL 的.c檔案中 需要 #include <linux/module.h> 檔案。
// 先寫函數
func_a ()
{
}
//再使用EXPORT_SYMBOL
EXPORT_SYMBOL(func_a);linux2.6的“/proc/kallsyms”檔案對應著核心符號表,記錄了符號以及符號所在的記憶體位址。模組可以使用如下宏匯出符號到核心符號表:
EXPORT_SYMBOL(符號名);
EXPORT_SYMBOL_GPL(符號名)
匯出的符號可以被其他模組使用,不過使用之前一定要extern聲明一下。EXPORT_SYMBOL_GPL()只適用於包含GPL許可權的模組。
舉一個代碼示範:
一個檔案是hello.c檔案,定義2個函數,用於匯出
#ifndef _KERNEL_
#define _KERNEL_
#endif
#ifndef MODULE
#define MODULE
#endif
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
int add_integar(int a,int b)
{
return a + b;
}
int sub_integar(int a,int b)
{
return a - b;
}
EXPORT_SYMBOL(add_integar);
EXPORT_SYMBOL(sub_integar);
另一個檔案是test.c 用於調用hello模組匯出的函數
#ifndef _KERNEL_
#define _KERNEL_
#endif
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
extern int add_integar(int ,int); //聲明要調用的函數
extern int sub_integar(int ,int); //聲明要調用的函數
int result(void)
{
int a,b;
a = add_integar(1,1);
b = sub_integar(1,1);
printk("%d/n",a);
printk("%d/n",b);
return 0;
}
兩個檔案編譯都要有對應的makefile。模板如下:
ifeq ($(KERNELRELEASE),)
# Assume the source tree is where the running kernel was built
# You should set KERNELDIR in the environment if it's elsewhere
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
# The current directory is passed to sub-makes as argument
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
modules_install:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
.PHONY: modules modules_install clean
else
# called from kernel build system: just declare what our modules are
obj-m := hello.o
endif
把hello.o改成對應的檔案名稱.o就可以了。分別make後,先載入hello模組,再載入test模組。然後cat /proc/kallsyms | grep integar,顯示:
f8eae000 u add_integar [hello2]
f8eae004 u sub_integar [hello2]
f8eae02c r __ksymtab_sub_integar [hello]
f8eae03c r __kstrtab_sub_integar [hello]
f8eae034 r __ksymtab_add_integar [hello]
f8eae048 r __kstrtab_add_integar [hello]
f8eae000 T add_integar [hello]
f8eae004 T sub_integar [hello]
可以看出符號表的名字和對應的記憶體位址。EXPORT_SYMBOL標籤內定義的函數對全部核心代碼公開,不用修改核心代碼就可以在您的核心模組中直接調用。
原文地址:http://blog.csdn.net/lisan04/archive/2009/04/16/4076013.aspx