使用EXPORT_SYMBOL

       在Linux内核里,我们编写驱动程序时,如果遇到的驱动太大,需要在各个模块之间共享一些变量或函数等,此时就需要用到内核里的EXPORT_SYMBOL宏了,其在include/linux/export.h文件中定义,而最常用的有如下两个:

#define EXPORT_SYMBOL(sym)                                      \
        __EXPORT_SYMBOL(sym, "")

#define EXPORT_SYMBOL_GPL(sym)                                  \
        __EXPORT_SYMBOL(sym, "_gpl")

       其中,多加了_GPL尾的量需要在使用MODULE_LICENSE()宏定义为GPL协议的模块里才能引用,不然加载驱动时会有类似Unknown symbol export_orig_gpl (err 0)的提示(该提示取自下面的例子),当然,模块之间也需要有加载先后顺序,其中EXPORT的模块需先加载,extern的后加载,不然也会有类似如上的提示。

       这里的例子会用到两个源码文件,作为export的文件名为export_orig.c,作为extern的文件名为export_symbol_example.c,相应的源码如下:

       export_orig.c:

#include
#include

static int export_orig_normal;
static int export_orig_gpl;

EXPORT_SYMBOL(export_orig_normal);
EXPORT_SYMBOL_GPL(export_orig_gpl);

static __init int export_orig_init(void)
{
    printk("Enter %s\n", __func__);
    export_orig_normal = 10;
    export_orig_gpl = 20;

    return 0;
}

static __exit void export_orig_exit(void)
{
    printk("Bye export_orig!\n");
}

module_init(export_orig_init);
module_exit(export_orig_exit);

       export_symbol_example.c:

#include 
#include

extern int export_orig_normal;
extern int export_orig_gpl;

MODULE_LICENSE("GPL");

static __init int export_symbol_example_init(void)
{
    printk("Enter %s\n", __func__);
    printk("export_orig_normal=%d\n", export_orig_normal);
    printk("export_orig_gpl=%d\n", export_orig_gpl);

    return 0;
}

static __exit void export_symbol_example_exit(void)
{
    printk("Bye export_symbol example!\n");
}

module_init(export_symbol_example_init);
module_exit(export_symbol_example_exit);

       相应的Makefile内容如下:

obj-m += export_symbol_example.o export_orig.o

CUR_PATH:=$(shell pwd)
LINUX_KERNEL_PATH:=/home/xinu/linux-3.13.6

all:
    make -C $(LINUX_KERNEL_PATH) M=$(CUR_PATH) modules

clean:
    make -C $(LINUX_KERNEL_PATH) M=$(CUR_PATH) clean

       接下来就可以make再insmod测试下了,注意模块间的加载顺序,建议做如下测试:

       1.先加载export_symbol_example.ko,再看看dmesg的输出;
       2.去掉export_symbol_example.c里的MODULE_LICENSE(“GPL”);再测试下。

       测试完后,现在可以清楚了解到整个export symbol与extern symbol的使用了吧,当然也不仅仅在变量,也可以export函数啊,自已测试玩玩看吧。

你可能感兴趣的:(使用EXPORT_SYMBOL)