首页 > 其他分享 >EXPORT_SYMBOL机制

EXPORT_SYMBOL机制

时间:2023-02-11 22:23:46浏览次数:31  
标签:__ 符号 SYMBOL sym EXPORT 内核 机制

Linux内核由主内核ELF格式文件(vmlinux)和许多内核模块组成。在构成vmliunx主内核文件中,每一个被声明EXPORT_SYMBOL的符号,都只有一个目的,就是让vmlinux主内核文件之外的内核模块使用这个变量或者函数符号,这个就是给到内核模块来使用的内核导出符号。

组成vmlinux主内核的所有文件(静态)都在同一时间编译和生成,即所有的符号引用都在静态链接阶段完成了。而内核模块的出现让事情有了变化(可能在后期动态加入),内核模块不可避免要使用主内核提供的基础设施(比如变量或者函数),作为独立编译链接的内核模块,必须解决符号引用的问题,也称为‘未解决引用’。 处理 “未解决引用” 问题的本质是在模块加载期间找到当前 “未解决的引用” 符号在内存中的实际目标地址。

所以当内核配置不支持动态加载ko时,EXPORT_SYMBOL宏为空

内核和内核模块通过符号表的形式向外部世界导出符号的相关信息,这种导出符号的方式在代码实现是通过EXPORT_SYMBOL宏的形式。

符号:全局变量或函数

符号表:每个导出符号对应一个结构体,如下。只存此类结构体地址的section称为符号表。

struct kernel_symbol {
    unsigned long value; // 符号的内存地址
    const char *name;    // 符号名对应的字符串地址,如"g_XXX"
    const char *namespace; // 指示是内核符号还是内核模块符号
};

 

 

EXPORT_SYMBOL:

#define EXPORT_SYMBOL(sym)        _EXPORT_SYMBOL(sym, "")

#define _EXPORT_SYMBOL(sym, sec)    __EXPORT_SYMBOL(sym, sec, "")

#define __EXPORT_SYMBOL(sym, sec, ns)    ___EXPORT_SYMBOL(sym, sec, ns)

#define ___EXPORT_SYMBOL(sym, sec, ns)                        \
    extern typeof(sym) sym;                            \
    extern const char __kstrtab_##sym[];                    \
    extern const char __kstrtabns_##sym[];                    \
    __CRC_SYMBOL(sym, sec);                            \
    asm("    .section \"__ksymtab_strings\",\"aMS\",%progbits,1    \n"    \
        "__kstrtab_" #sym ":                    \n"    \
        "    .asciz     \"" #sym "\"                    \n"    \
        "__kstrtabns_" #sym ":                    \n"    \
        "    .asciz     \"" ns "\"                    \n"    \
        "    .previous                        \n");    \
    __KSYMTAB_ENTRY(sym, sec)

#define __KSYMTAB_ENTRY(sym, sec)                    \
    static const struct kernel_symbol __ksymtab_##sym        \
    __attribute__((section("___ksymtab" sec "+" #sym), used))    \
    __aligned(sizeof(void *))                    \
    = { (unsigned long)&sym, __kstrtab_##sym, __kstrtabns_##sym }

 

EXPORT_SYMBOL(sym)展开后为:定义一个 struct kernel_symbol 类型的变量,存在名为 "___ksymtab+sym" 的 section中。

 

insmod时,模块寻找依赖的符号,就是在___ksymtab+sym中遍历。从name指针获取函数名字符串,比对一致后,获取value值(内核函数指针)。即模块需要的符号。

 

编译内核后,会生成 vmlinux.symvers、modules-only.symvers、Module.symvers 这三个以 .symvers 后缀的文件,里面就是导出符号的信息

 

 

 

 

 

 

 

 

 

标签:__,符号,SYMBOL,sym,EXPORT,内核,机制
From: https://www.cnblogs.com/god-of-death/p/17112692.html

相关文章

  • WPF数据绑定机制是如何实现 转载
    转载自https://blog.51cto.com/u_15127553/4275829 接触MVVM模式也有一段时间了,这种将前后台分离开了的设计模式一下子就吸引了我,也是当时一直有一个问题困扰了我很久:WP......
  • 6.2 RLE算法的机制
    把文件内容用“数据×重复次数”的形式来表示的压缩方法称为RLE(RunLengthEncoding,行程长度编码)算法(图6-2) RLE算法是一种很好的压缩方法,经常被用于压缩传真的图像......
  • printf的缓冲机制
    printf的缓冲机制参考链接:https://www.cnblogs.com/sinferwu/p/12426410.htmlprintf是C库函数,是对系统调用write的封装,有其特有的缓冲机制。printf函数实际上只是输出到......
  • JQuery插件机制
    jQuery-插件机制增强JQuery的功能1.实现方式:1.$.fn.extend(object)增强通过Jquery获取的对象的功能$("#id")2.$.extend(object)......
  • django更多关联模型使用import-export导入
    再次用import-export导入一个模型创建模型创建Course_real模型,修改app的models.py,,为实际开课信息,其中主要难点在计算字段的设置,用函数定义了work_load字段,但是其调用存在......
  • day06-SpringMVC底层机制简单实现-02
    SpringMVC底层机制简单实现-02https://github.com/liyuelian/springmvc-demo.git4.任务3-从web.xml动态获取容器配置文件4.1分析任务3:MyDispatcherServlet(自定义的......
  • module_init机制
    模块代码有两种运行方式,一是静态编译连接进内核,在系统启动过程中进行初始化;一是编译成可动态加载的module,通过insmod动态加载重定位到内核。这两种方式可以在Makefile中通......
  • RPC优雅关闭机制详解
    1关闭为什么有问题?系统为啥非要拆分?更方便、更快速迭代业务,但也得经常更新应用系统,时不时还老要重启服务器。重启服务过程中,RPC怎么做到让调用方系统不出问题?2上线流程当......
  • python的垃圾回收机制
    1.垃圾回收机制的算法分类python垃圾回收算法通常有三类:引用计数,标记清除和分代回收,主要以引用计数为主,标记清除和分代回收为辅 2.对象的存储方式——refchain环......
  • 79、异常机制
    当认证微服务通过数据校验后,要远程调用用户/会员模块进行真正的注册。我们要检查用户提交的用户名和手机号等在数据库是否已经存在了。我们可以通过boolean值判断是否已经......