• linux模块使用外部符号


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

    1、定义说明

    把内核函数的符号导出,也可以理解成将函数名作为符号导出;符号的意思就是函数的入口地址,或者说是把这些符号和对应的地址保存起来的,在内核运行的过程中,可以找到这些符号对应的地址的。

    2、相关处理

    (1)、对编译所得的.ko进行strip -S,处理掉调试信息,这样可以大大缩小ko文件的大小;

    (2)、使用KBUILD_EXTRA_SYMBOLS

    3、使用方法

    1、在模块函数定义之后使用“EXPORT_SYMBOL(函数名)”来声明。
    2、在调用该函数的另外一个模块中使用extern对之声明。
    3、先加载定义该函数的模块,然后再加载调用该函数的模块,请注意这个先后顺序。

    主要使用于下面这样的场合:

    有两个我们自己的模块,其中Module B使用了Module A中的export的函数,因此在Module B的Makefile文件中必须添加:

    KBUILD_EXTRA_SYMBOLS += /path/to/ModuleA/Module.symvers
    
    export KBUILD_EXTRA_SYMBOLS
    
    • 1
    • 2
    • 3

    这样在编译Module B时,才不会出现Warning,提示说func1这个符号找不到,而导致编译得到的ko加载时也会出错。

    // Module A (mod_a.c)
    #include<linux/init.h>
    #include<linux/module.h>
    #include<linux/kernel.h>
     
    static int func1(void)
    {
     
           printk("In Func: %s...\n",__func__);
           return 0;
     
    }
    // Export symbol func1
     
    EXPORT_SYMBOL(func1);
     
    static int __init hello_init(void)
    {
           printk("Module 1,Init!\n");
           return 0;
    }
     
    static void __exit hello_exit(void)
    {
           printk("Module 1,Exit!\n");
    }
     
    module_init(hello_init);
    module_exit(hello_exit);
     
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    // Module B (mod_b.c)
    #include<linux/init.h>
    #include<linux/kernel.h>
    #include<linux/module.h>
     
    static int func2(void)
    {
           extern int func1(void);
           func1();
           printk("In Func: %s...\n",__func__);
           return 0;
    }
     
    static int __init hello_init(void)
    {
           printk("Module 2,Init!\n");
           func2();
           return 0;
    }
     
    static void __exit hello_exit(void)
    {
        printk("Module 2,Exit!\n");
     
    }
     
    module_init(hello_init);
    module_exit(hello_exit);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
  • 相关阅读:
    【QT】自定义组件ui类添加到主ui界面方法
    【电源专题】LDO的电源抑制比(PSRR)
    SVG 基本语法
    java实验报告2:三种结构综合案例练习
    递归的总结和案例
    取址运算符&和间接寻址运算符*
    vue-element-admin 综合开发五:引入 echarts,封装echarts 组件
    二叉树实现(创建,遍历)
    216. 组合总和 III
    【重大消息】报告称OpenAI的产品可经由微软的服务提供给中国客户
  • 原文地址:https://blog.csdn.net/sinat_42884063/article/details/125595917