首页 > 其他分享 >KO之间互相调用

KO之间互相调用

时间:2023-05-21 20:45:49浏览次数:29  
标签:调用 KO modules 互相 ko init func moduleB moduleA

需求

假设有两个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的使用步骤:

  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,modules,互相,ko,init,func,moduleB,moduleA
From: https://www.cnblogs.com/mrlayfolk/p/17419124.html

相关文章

  • python类中调用类方法时,报错self参数未填
    转载:(14条消息)python类中调用类方法时,报错self参数未填。_追天一方的博客-CSDN博客又碰到了一个小错误比如一个类如下:classprint_number(object):def__init__(self,string="数字是"):self.string=stringdefprint_(self,ss=3):print("{}:{}".......
  • 2023/5/21每日随笔 调用chatgpt接口实现项目的基本需要
    首先,对于我要求的工作,gpt完美胜任,那么问题来了,怎么调用chatgpt,是可以免费调用的,但需要keyword,也就得进入chatgpt官网,就得用外网,但是要它的api应用到android上,外网手段就不可取了,于是,准备冲别人搭建的平台上调用,很幸运的是,在B站上还真的找到资源,up主也很好,教我一步一实现,搭建了以......
  • odoo后台调用路由接口
    fromodoo.exceptionsimportUserErrorimportrequestsfromodoo.httpimportrequestdefaction_commit_approval(self,action_type='commit_approval'):"""action_type:commit_approval/cancel_approval......
  • 2.索引数组和关联数组,求随机数,递归调用
    总结索引数组和关联数组,字符串处理,高级变量使用及示例。数组1.数组介绍变量:存储单个元素的内存空间数组;存储多个元素的连续的内存空间,相当于多个变量的集合。数组名和索引索引的编号从0开始,属于数组索引索引支持自定义的格式,而不仅是数值格式,即为关联索引。Bash的数组支持稀疏格......
  • java中使用jep调用python类
    经过调研,目前这应该只有一种调用方式了,那就是使用jep,后来亲测了以下确实是可行,我是使用jep调用了一个python文件中的类,并测试了类的一个方法,可以正常执行,但是具体速度会不会慢很多,我还没有测试。刚开始在调研的时候,说jython也可以调用,但是这个包只支持2.7python,毕竟现在很少有用2......
  • 跨域JSONP原理及调用具体示例
    上篇博客介绍了同源策略和跨域访问概念,其中提到跨域常用的基本方式:JSONP和CORS。 那这篇博客就介绍JSONP方式。  JSONP原理  在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但img、iframe、script等标签是个例外,这......
  • python基础-进程池、submit同异步调用、shutdown参数、ProcessPoolExecutor进程池、进
    转载:(14条消息)python基础-进程池、submit同异步调用、shutdown参数、ProcessPoolExecutor进程池、进程池ftp_pythonsubmit_易辰_的博客-CSDN博客引入进程池在学习线程池之前,我们先看一个例子frommultiprocessingimportProcessimporttimedeftask(name):print(......
  • 深度学习--调用chatgot接口实现
    首先,对于段落文字进行提取主要信息,第一反应要是电脑像人脑就行了,就想到chatgpt进行识别,以下为我识别的文字进行gpt转换。实验结果成立,现在只需要将接口调用,将识别文字传入后,进行字符串拼接,加上:“提取支付时间,消费类型,消费内容”,传入gpt后,将结果返回,输入到程序上,进行识别即可。......
  • Golang的viper包调用多次OnConfigChange
    问题:修改了一次,而执行了两次这个函数解决方案把配置文件进行md5,保存其md5值。在调用这个函数时,再次读取文件进行md5。两者比对,如果相等就不执行下面的逻辑。这样就解决了,一模一样的配置文件,保存多次,不会执行后续的逻辑。但是,杜绝了大部分的场景,比如修改了一次,保存了两次......
  • 远程调用——Feign
    使用RestTemplate发起远程调用存在的问题1.代码可读性差,编程体验不统一2.参数复杂URL难以维护Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign。其作用就是帮助我们优雅的实现http请求的发送,解决RestTemplate的问题。使用步骤1.引入依赖点击查看......