linux export_symbol 变量,Linux的EXPORT_SYMBOL和EXPORT_SYMBOL_GPL的使用和区别

简要说明使用方法:

一个模块mod1中定义一个函数func1;在另外一个模块mod2中定义一个函数func2,func2调用func1。

在模块mod1中,EXPORT_SYMBOL(func1);

在模块mod2中,extern int func1();

就可以在mod2中调用func1了。

同理EXPORT_SYMBOL_GPL使用相同。

1、EXPORT_SYMBOL的作用是什么?

EXPORT_SYMBOL标签内定义的函数或者符号对全部内核代码公开,不用修改内核代码就可以在您的内核模块中直接调用,即使用EXPORT_SYMBOL可以将一个函数以符号的方式导出给其他模块使用。

这里要和System.map做一下对比:

System.map 中的是连接时的函数地址。连接完成以后,在2.6内核运行过程中,是不知道哪个符号在哪个地址的。

EXPORT_SYMBOL的符号,是把这些符号和对应的地址保存起来,在内核运行的过程中,可以找到这些符号对应的地址。而模块在加载过程中,其本质就是能动态连接到内核,

如果在模块中引用了内核或其它模块的符号,就要EXPORT_SYMBOL这些符号,这样才能找到对应的地址连接。

2、使用方法

第一、在模块函数定义之后使用EXPORT_SYMBOL(函数名);

第二、在调用该函数的模块中使用extern对之声明;

第三、首先加载定义该函数的模块,再加载调用该函数的模块;

3、区别

EXPORT_SYMBOL(name);

EXPORT_SYMBOL_GPL(name);

这两个宏均用于将给定的符号导出到模块外, _GPL版本的宏定义只能使符号对GPL许可的模块可用。 符号必须在模块文件的全局部分导出,不能在函数中导出,

这是因为上述这两个宏将被扩展成一个特殊用途的声明,而该变量必须是全局的。这个变量存储于模块的一个特殊的可执行部分(一个"ELF段" ),在装载时,内核通过这个段来寻找模块导出的变量

(感兴趣的读者可以看获知更详细的信息)。

EXPORT_SYMBOL举例说明

1、函数方面的使用:

例如我下面的例子,在一个驱动中drivers/video/lt9211/lt9211.c定义了函数lt9211_mipitolvds_init,然后在另外的.c文件中可以直接extern来使用:

943 void lt9211_mipitolvds_init(void)

944 {

945         lt9211_config();

946

947         lt9211_timingset();

948         if( pvideo_format != NULL )

949         {

950         lt9211_desscpll();

951         lt9211_mipipcr();

952

953         //Tx config

954         lt9211_txphy();

955         lt9211_txdigital();

956         lt9211_txpll();

957 #ifdef LT9211_VEDIO_CHECK_DEBUG

958         lt9211_videocheckdebug();

959 #endif

960

961 #ifdef LT9211_BT_SET

962         lt9211_BT_set();

963 #endif

964         }

965

966     mdelay(50);

967 }

968 EXPORT_SYMBOL(lt9211_mipitolvds_init);

1234567891011121314151617181920212223242526

直接exterm来使用:

43 extern void lt9211_mipitolvds_init(void); //首先从其他地方extern过来

...

635 static int panel_simple_enable(struct drm_panel *panel)

636 {

637         struct panel_simple *p = to_panel_simple(panel);

638

639         if (p->enabled)

640                 return 0;

641

642         /* add for lt9211 resume/suspend init */

643         lt9211_mipitolvds_init();  //这里是对函数的调用

644

645         if (p->desc && p->desc->delay.enable)

646                 panel_simple_sleep(p->desc->delay.enable);

647

648         backlight_enable(p->backlight);

649

650         p->enabled = true;

651

652         return 0;

653 }

12345678910111213141516171819202122

2、变量方面的使用

首先在一个.c文件中定义:

int gyro_lsm9ds1_x = 0;

EXPORT_SYMBOL(gyro_lsm9ds1_x);

12

然后在另外的.c中extern过来使用:

extern int gyro_lsm9ds1_x;

————————————————

版权声明:本文为CSDN博主「只是一些暗恋而已」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_30624591/article/details/101756167

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值