KO之间互相调用

这篇具有很好参考价值的文章主要介绍了KO之间互相调用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

需求

假设有两个KO,命名为moduleA.KO,moduleB.KO,现在要实现在moduleB.KO中调用moduleA.KO中的函数。

实现

ModuleA实现

源码:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

void moduleA_func(void)
{
    printk("moduleA function\r\n");
}

static int __init moduleA_init(void)
{
    printk("moduleA init!\r\n");

    return 0;
}

static void __exit moduleA_exit(void)
{
    printk("moduleA exit!\r\n");
}

EXPORT_SYMBOL_GPL(moduleA_func);

MODULE_AUTHOR("moduleA");
MODULE_DESCRIPTION("moduleA functions");
MODULE_LICENSE("GPL v2");

module_init(moduleA_init);
module_exit(moduleA_exit);

moduleA导出符号moduleA_func。

编译Makefile实现:

# Kernel modules
obj-m += moduleA.o

KVERS = $(shell uname -r)

# Specify flags for the module compilation.
#EXTRA_CFLAGS=-g -O0

OUTPUT_DIR := $(shell pwd)

build: kernel_modules

kernel_modules:
	make -C /lib/modules/$(KVERS)/build M=$(OUTPUT_DIR) modules

clean:
	make -C /lib/modules/$(KVERS)/build M=$(OUTPUT_DIR) clean

编译:

$ make
$ more Module.symvers
0xcaecb33a      moduleA_func    /home/grace/ko_test/moduleA/moduleA     EXPORT_SYMBOL_GPL

可以看出,moduleA_func已经在导出的符号表中了。

ModuleB实现

源码:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

extern void moduleA_func(void);

static int __init moduleB_init(void)
{
    printk("moduleB init!\r\n");

    moduleA_func();

    return 0;
}

static void __exit moduleB_exit(void)
{
    printk("moduleB exit!\r\n");
}

MODULE_AUTHOR("moduleB");
MODULE_DESCRIPTION("moduleB functions");
MODULE_LICENSE("GPL v2");

module_init(moduleB_init);
module_exit(moduleB_exit);

编译Makefile:

# Kernel modules
obj-m += moduleB.o

KVERS = $(shell uname -r)

# Specify flags for the module compilation.
#EXTRA_CFLAGS=-g -O0

# 引用moduleA.ko的符号表, 需要先编译SDK才能得到, 路径为绝对路径
KBUILD_EXTRA_SYMBOLS += /home/grace/ko_test/moduleA/Module.symvers

OUTPUT_DIR := $(shell pwd)

build: kernel_modules

kernel_modules:
	make -C /lib/modules/$(KVERS)/build M=$(OUTPUT_DIR) modules

clean:
	make -C /lib/modules/$(KVERS)/build M=$(OUTPUT_DIR) clean

测试

1、插入moduleA.ko

$ sudo insmod moduleA.ko
$ sudo dmesg -c
[ 1567.642413] moduleA: loading out-of-tree module taints kernel.
[ 1567.642507] moduleA: module verification failed: signature and/or required key missing - tainting kernel
[ 1567.642823] moduleA init!
$ cat /proc/kallsyms | grep moduleA_func
ffffffffc071b030 r __ksymtab_moduleA_func       [moduleA]
ffffffffc071b07b r __kstrtab_moduleA_func       [moduleA]
ffffffffc071b040 r __kcrctab_moduleA_func       [moduleA]
ffffffffc071a000 t moduleA_func [moduleA]

2、插入moduleB.ko

$ sudo dmesg -c
[ 1900.514577] moduleB init!
[ 1900.514580] moduleA function

可以看出,moduleB成功调用到了moduleA的moduleA_func函数。

常见错误

1、moduleA没有编译就编译了ModuleB

这时候会提示:WARNING: "moduleA_func" [/home/grace/ko_test/moduleB/moduleB.ko] undefined!

2、没有在ModuleB的Makefile中添加KBUILD_EXTRA_SYMBOLS

这时候会提示:WARNING: "moduleA_func" [/home/grace/ko_test/moduleB/moduleB.ko] undefined!

3、注意:KBUILD_EXTRA_SYMBOLS后面跟的是绝对路径

总结

ModuleB.ko调用ModuleA.ko的使用步骤:文章来源地址https://www.toymoban.com/news/detail-453612.html

  1. 先编译ModuleA.ko, 得到KO的符号表, 也就是Module.symvers文件
  2. 再编译ModuleB.ko, 需要在Makefile中指定ModuleA.ko的符号表位置KBUILD_EXTRA_SYMBOLS+="符号表位置",并且使用绝对路径方式。
  3. 插入时,需要先插入ModuleA.ko,再插入ModuleB.ko
  4. 卸载时,需要先卸载ModuleB.ko,再卸载ModuleA.ko,否则会提示:rmmod: ERROR: Module moduleA is in use by: moduleB

到了这里,关于KO之间互相调用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 内核是如何运行ko文件的--系统调用

    现在我们己经知道insmod命令做了什么事情,当我们使用insmod命令加载ko文件的时候,会调用系统调用init_module和finit_module。那什么是系统调用呢? 系统调用是操作系统扌是供给编程人员的接囗,当编程人员写程序时,因为上层应用不能直接操作硬件,所以就要利用系统调用接

    2024年02月01日
    浏览(30)
  • 基于Ko-time的Springboot单体化调用链追踪实践

    目录 前言 一、关于Ko-Time 1、是什么?  2、ko-time更新时间线 二、Ko-time怎么用? 1、依赖引入 2、配置集成 3、权限放行 三、链路追踪  1、系统运行  2、链路追踪  3、长时间调用模拟  总结         熟悉微服务的老司机一定了解,在微服务模式下,在一次调用链路中,可

    2024年02月15日
    浏览(32)
  • Docker 容器之间的互相通信

    步骤一:创建自定义网络 首先,我们需要创建一个自定义网络,以便容器可以连接到这个网络上,从而实现互相通信。在命令行中执行以下命令: 这将创建一个名为 ddz 的自定义网络。 步骤二:运行第一个容器并连接到自定义网络 现在,我们可以运行第一个容器,并将其连

    2024年01月16日
    浏览(34)
  • linux系统之间互相传输文件

    目录 一、两种方式 二、scp (1)发送 (2)下载 (3)远程到远程 三、sftp 四、使用图像化工具 scp和sftp; 都是通过ssh服务实现的 本机——远程服务器 把本机当前路径下的1.txt文件,发送到远程服务器的家目录 scp 1.txt   steven@192.168.2.133:/home/steven 把本机当前路径下的dir文件夹

    2024年02月07日
    浏览(29)
  • java--- xml和对象之间的互相转换

    第一种方法是使用 JAXB(Java Architecture for XML Binding) 实现XML与Bean的相互转换 简介 JAXB 是一个业界的标准,是一项可以根据 XML Schema 产生 Java 类的技术。该过程中, JAXB 也提供了将XML实例文档反向生成 Java 对象树的方法,并能将 Java 对象树的内容重新写到  XML 实例文档。 Jaxb

    2024年02月04日
    浏览(67)
  • Java中Map与对象之间互相转换

            Map在日常开发应用中的频率很高,最常用的实现类是HashMap和有序的TreeMap。在企业级应用中,更多的应用场景是关联JSON和Object使用,Map可以用于JSON传参、接收JSON参数,返回JSON数据等,也可以用于对象处理,开发者可以省一些简单实体类,用map来替代。       

    2024年02月04日
    浏览(29)
  • 微信小程序和H5之间互相跳转、互相传值

      微信小程序和内嵌 H5 之间来回跳转,来回交互。   微信小程序官方提供了 web-view 组件来实现微信小程序跳转到 H5 页面,实现的方式也很简单,具体实现方式如下: 1、新建一个页面用来单独存放 web-view 组件,并且所有的内嵌 H5 都可以通过这个页面来实现跳转; (

    2024年02月02日
    浏览(31)
  • Java中十六进制与十进制之间互相转换

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 提示:这里可以添加本文要记录的大概内容: 提示:以下是本篇文章正文内容,下面案例可供参考 话不多说,直接上代码 如将十进制数字 108 转换为十六进制 代码示例如下: 运行结果: 这样将一个十

    2024年02月12日
    浏览(41)
  • 【Vue3】3-3 : 组件之间是如何进行互相通信的

    本书目录:点击进入 一、组件之间为什么要做通信 二、组件之间通信方式 2.1、父传子:由传递属性实现 stage 1:申明 (即定义) stage 2:注册 stage 3:使用 【示例】:父组件将 title 和 count 传递给子组件 (普通数据 和 响应式数据的传递) >  代码  >  效果 2.2、子传父

    2024年01月17日
    浏览(27)
  • 阿里云物联网平台如何通过云产品流转使两个设备互相通信

    目录 前言: 一、创建产品  二、设置云产品流转  三、测试  参考: 之间使用MQTT协议主要用于设备与云平台的通信,最近涉及到了两个ESP32之间的通信,所以了解到了阿里云的云产品流转。 而我们想要达到的目的是:   创建 产品 ,在此产品下创建 两个设备  设置产品名

    2024年01月16日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包