• 两个内核模块之间的交互


    这里的通信可以简单点理解,就是模块B如何调用A的函数,变量或者常量。为了简化,我设计一个模块A中的一个函数为printMSG,原型为int printMSG(int n);传入的参数n表示打印几遍一个固定的字符串。模块A()源码:

    其中用到了EXPORT_SYMBOL宏来表明导出printMSG这个符号。还有一个EXPORT_SYMBOL_GPL宏,导出的符号具有GPL授权。内核所有的导出符号可以通过 : cat /proc/kallsyms来查看,太多了,所以最好导出到一个文件中慢慢看。在其中就可以发现printk等等我们常见的内核函数。(理解为都是通过内核符号表中的进行交互。linux所谓的LKM有了更深的认识。内核其实就是一个大的程序,当我们动态的加载进入一个模块时,他还是内核这个大程序的一部分,所以我们可以像一个工程中那样,将函数导出到内核符号表中,再将需要调用的外部的函数声明为extern关键字,就可以方便的调用了)

    分别编写两个文件的Makefile文件,先insmod b.ko,再insmod a.ko出现错误:
    a:no symbol version for printmsg
    a:unknown symbol printmsg(err -22)
    原因:
    这是linux kernel 2.6.26 之后版本的bug (详细描述, 请看
    http://bugzilla.kernel.org/show_bug.cgi%3Fid%3D12446)
    并且这个bug不会被fix
    解决办法是把mod_a的Module.symvers放到mod_b的当前路径,从而编译mod_b,符号信息会自动
    连接进去.
    或者在mod_b的makefile中使用KBUILD_EXTRA_SYMBOLS指定mod_a的Module.symvers, 如:
    KBUILD_EXTRA_SYMBOLS=/mod_a/Module.symvers
    编译mod_b时,搜索Module.symvers的路径是:
    1, kernel source path, e.g. /usr/src/kernels/linux-2.6.28.10
    2, makefile中M=所指定的路径, 它等效于变量KBUILD_EXTMOD的值
    3, 变量KBUILD_EXTRA_SYMBOLS的值
    只要将上面的测试程序中的caller的makefile中加上“KBUILD_EXTRA_SYMBOLS”就好了�里面已经有了去掉注释�路径改下�但必须是绝对路径。重新编译caller模块即可。 
  • 相关阅读:
    Android开发 设置控件边角半圆
    Android开发 使用XML文件设置背景变化
    Android开发 ImageButton加载drawable文件问题
    Android开发 网络检测(使用广播监听)
    android studio无法在可视化页面预览布局文件
    jdbc连接oracle数据库
    「数学」- 暑假后文化课能力复健 20210906 ~ 20210912
    「数学」- 暑假后文化课能力复健 20210830 ~ 20210905
    「数学」高等代数学习笔记
    「数学」浅谈极值点偏移问题的处理技巧
  • 原文地址:https://www.cnblogs.com/scu-cjx/p/6878758.html
Copyright © 2020-2023  润新知