• 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
  • 相关阅读:
    C++——类和对象(中)(1)
    DDL:针对于数据库、数据表、数据字段的操作
    纯CSS制作3D动态相册【流星雨3D旋转相册】HTML+CSS+JavaScriptHTML5七夕情人节表白网页制作
    2020 ICPC 澳门(G,J,I)详解
    抽象类、模板方法模式
    boost 库记录
    【ARXML专题】-25-定义接收一组特定range范围的Rx CAN ID
    Goland快捷键整理
    神经网络的数学方法及应用,神经网络的数学理论
    07设计模式-结构型模式-桥接模式
  • 原文地址:https://blog.csdn.net/sinat_42884063/article/details/125595917