当前位置:首页 > 公众号精选 > 嵌入式客栈
[导读][导读] 写驱动时,常常遇到EXPORT_SYMBOL,这究竟做了啥,对于做底层开发而言,了解其内在实现机制,对于开发还是很有益的。本文就来剖析一下其内在实现机制及其作用。从本文开始,将开始不定期更新阅读内核代码的笔记,内核代码庞大,且限于水平,如发现错误

[导读] 写驱动时,常常遇到EXPORT_SYMBOL,这究竟做了啥,对于做底层开发而言,了解其内在实现机制,对于开发还是很有益的。本文就来剖析一下其内在实现机制及其作用。从本文开始,将开始不定期更新阅读内核代码的笔记,内核代码庞大,且限于水平,如发现错误,文末开了个小程序留言功能进行讨论,真诚欢迎讨论交流。让我们一起来阅读内核代码吧~~~

概要介绍

内核代码中几个常见用于导出符号的宏为:

#define EXPORT_SYMBOL(sym)
#define EXPORT_SYMBOL_GPL(sym)
#define EXPORT_SYMBOL_GPL_FUTURE(sym)
#define EXPORT_UNUSED_SYMBOL(sym)
#define EXPORT_UNUSED_SYMBOL_GPL(sym)

其作用分别为:

  • EXPORT_SYMBOL:导出一般符号,用于使内部符号变成可加载模块。可加载模块的含义是可以通过命令insmod 动态加载内核模块。

  • EXPORT_SYMBOL_GPL:导出只兼容GPL License的符号,这些符号仅对具有GPL兼容许可证的模块可用。GPL-only符号的可能意图:

  • 已有符号,限定使用该符号的模块都只能是内核的派生产品。

  • 对于新创建的符号,其创建者可以通过这个机制限定其仅适用于GPL。

  • EXPORT_SYMBOL_GPL_FUTURE ,其目的是标记将来可能被更改为GPL-only导出的符号。如果非GPL模块使用了此类符号,则内核将发出警告,表明该模块将在将来的某个时间中断。幸运的是,这些警告将帮助专有模块的作者提前为更改做好准备。

  • EXPORT_UNUSED_SYMBOL, EXPORT_UNUSED_SYMBOL_GPL这两个基本没用,估计是预留接口。

以内核调度器举例,先不关心函数内部实现细节。

asmlinkage __visible void __sched schedule(void)
{
    struct task_struct *tsk = current;

    sched_submit_work(tsk);
    do {
        preempt_disable();
        __schedule(false);
        sched_preempt_enable_no_resched();
    } while (need_resched());
}
EXPORT_SYMBOL(schedule);

其中:EXPORT_SYMBOL 宏定义为:

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

而__EXPORT_SYMBOL 的宏定义为:

#define __EXPORT_SYMBOL(sym, sec)                                \
    extern typeof(sym) sym;                                     \
    __CRC_SYMBOL(sym, sec)                                      \
    static const char __kstrtab_##sym[]                         \
    __attribute__((section("__ksymtab_strings"), aligned(1)))   \
    = VMLINUX_SYMBOL_STR(sym);                                  \
    extern const struct kernel_symbol __ksymtab_##sym;          \
    __visible const struct kernel_symbol __ksymtab_##sym        \
    __used                                                      \
    __attribute__((section("___ksymtab" sec "+" #sym), unused)) \
    = { (unsigned long)&sym, __kstrtab_##sym }

而__CRC_SYMBOL的宏定义为:

#define __CRC_SYMBOL(sym, sec)                                     \
    extern __visible void *__crc_##sym __attribute__((weak));    \
    static const unsigned long __kcrctab_##sym                   \
    __used                                                       \
    __attribute__((section("___kcrctab" sec "+" #sym), unused))  \
    = (unsigned long) &__crc_##sym;

这里还有个VMLINUX_SYMBOL_STR宏,其定义如下:

/* Some toolchains use a `_' prefix for all user symbols. */
#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX
#define __VMLINUX_SYMBOL(x) _##x
#define __VMLINUX_SYMBOL_STR(x) "_" #x
#else
#define __VMLINUX_SYMBOL(x) x
#define __VMLINUX_SYMBOL_STR(x) #x
#endif

#define VMLINUX_SYMBOL_STR(x) __VMLINUX_SYMBOL_STR(x)

假定CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX定义了,则全部展开为:


那么全部展开后,得到了什么呢?

    extern typeof(schedule) schedule;                                    \
    extern __visible void *__crc_schedule __attribute__((weak));         \
    static const unsigned long __kcrctab_schedule                        \
    __used                                                               \
    __attribute__((section("___kcrctab" sec "+" "schedule"), unused))    \
    = (unsigned long) &__crc_schedule;      
   static const char __kstrtab_schedule[]                                \
    __attribute__((section("__ksymtab_strings"), aligned(1)))            \
    = "_" "schedule";                                                    \
    extern const struct kernel_symbol __ksymtab_schedule;                \
    __visible const struct kernel_symbol __ksymtab_schedule              \
    __used                                                               \
    __attribute__((section("___ksymtabsec "+" "schedule"), unused))    \
    = {
 (unsigned long)&schedule, __kstrtab_schedule };    

这样还是不直观,去掉不必要的换行符,整理一下:

asmlinkage __visible void __sched schedule(void)
{
    struct task_struct *tsk = current;

    sched_submit_work(tsk);
    do {
        preempt_disable();
        __schedule(false);
        sched_preempt_enable_no_resched();
    } while (need_resched());

/*以下部分都属于EXPORT_SYMBOL(schedule)的展开*/
extern typeof(schedule) schedule;
extern __visible void *__crc_schedule __attribute__((weak));

static const unsigned long __kcrctab_schedule __used                 \
__attribute__((section("___kcrctab" sec "+" "schedule"), unused))    \
= (unsigned long) &__crc_schedule;     

static const char __kstrtab_schedule[] __attribute__((section("__ksymtab_strings"), aligned(1)))  = "_" "schedule";                                     

extern const struct kernel_symbol __ksymtab_schedule; 

__visible const struct kernel_symbol __ksymtab_schedule __used __attribute__((section("___ksymtabsec "+" "schedule"), unused)) = { 
    (unsigned long)&schedule, __kstrtab_schedule 
}; 

EXPORT_SYMBOL(schedule)展开成这么一个玩意儿,要理解其内在机制,这里涉及到了很多内核代码关键词,比如:

  • asmlinkage

  • __visible

  • extern typeof(schedule) schedule

  • kernel_symbol

  • ……

这个且待下回分解。

点击留言/查看留言

END

果喜欢右下点个在看,也会让我倍感鼓舞

往期精彩推荐




▲深度解析U-Boot网络实现(长篇好文)
读U-Boot源码-C语言编程大法总结篇一
读U-Boot源码-C语言编程技巧总结篇二
基于Buildroot的Linux系统构建之根文件系统
手把手教系列之移动平均滤波器C实现
手把手教系列之IIR数字滤波器设计实现

关注置顶:扫描左下二维码关注公众号加星

讨论加群:扫描右下二维码添加,发送“加群”

关注

加群

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

上海2024年4月17日 /美通社/ -- 在2024 F1中国站即将拉开帷幕之际,高端全合成润滑油品牌美孚1号今日举办了品牌50周年庆祝活动。三届F1年度车手总冠军马克斯•维斯塔潘也亲临现场,共同庆祝这一里程...

关键字: BSP 汽车制造 行业标准 产品系列

北京2024年4月17日 /美通社/ -- 2024年4月13日,由北京康盟慈善基金会主办的"县域诊疗,规范同行"——肿瘤诊疗学术巡讲项目首站在广州隆重召开。本次会议邀请全国多位肺癌领域专家和县域同道...

关键字: AI技术 医疗服务 BSP 互联网

海口2024年4月16日 /美通社/ -- 4月14日,在中法建交60周年之际,科学护肤先锋品牌Galenic法国科兰黎受邀入驻第四届中国国际消费品博览会(以下简称"消博会")法国馆。Galenic法...

关键字: NI IC BSP ACTIVE

上海2024年4月17日 /美通社/ -- 每年4月17日是世界血友病日。今年,世界血友病日以"认识出血性疾病,积极预防和治疗"为主题,呼吁关注所有出血性疾病,提升科学认知,提高规范化诊疗水平,让每一位出血性疾病患者享有...

关键字: VII 动力学 软件 BSP

伦敦2024年4月16日 /美通社/ -- ATFX宣布任命Siju Daniel为首席商务官。Siju在金融服务行业拥有丰富的经验和专业知识,曾在全球各地的高管职位上工作了19年以上。Siju之前担任FXCM首席商务官...

关键字: NI AN SI BSP

在这篇文章中,小编将为大家带来Linux内核的相关报道。如果你对本文即将要讲解的内容存在一定兴趣,不妨继续往下阅读哦。

关键字: 嵌入式 Linux 内核

常州2023年9月25日 /美通社/ -- 9月23日,由江苏省商务厅指导,世界中餐业联合会、常州市人民政府主办的"第三届中华节气菜大会暨首届江南美食节"在江苏常州开幕。文化和旅游部国际交流与合作局一...

关键字: BSP 可持续发展 大赛 质量控制

北京2023年9月25日 /美通社/ -- 9月21日,由中国质量报刊社·中国质量新闻网主办的第六届食品高质量发展交流会在北京举行,会议主题为"高质量,新生活",旨在推动食品行...

关键字: 自动化 BSP ISO9001 NAS

北京2023年9月23日 /美通社/ -- 近日,主线科技正式获准在北京市智能网联汽车政策先行区道路开启常态化测试与示范,将与物流客户在真实开放的城区道路场景中,率先开启基于L4级别自动驾驶能力的智能卡车运输示范。 随...

关键字: 智能卡 测试 高速公路 BSP
关闭
关闭