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的使用步骤:
- 先编译ModuleA.ko, 得到KO的符号表, 也就是Module.symvers文件
- 再编译ModuleB.ko, 需要在Makefile中指定ModuleA.ko的符号表位置KBUILD_EXTRA_SYMBOLS+="符号表位置",并且使用绝对路径方式。
- 插入时,需要先插入ModuleA.ko,再插入ModuleB.ko
- 卸载时,需要先卸载ModuleB.ko,再卸载ModuleA.ko,否则会提示:rmmod: ERROR: Module moduleA is in use by: moduleB
KO之间互相调用的更多相关文章
- Java特性之多态父类与子类之间的调用
问题描述: Java三大特性,封装.继承.多态,一直没搞懂其中多态是什么,最近研究了一下,关于父类和子类之间的调用.下面是一个测试类,源代码如下: package com.test; public c ...
- html iframe 元素之间的调用
html iframe 元素之间的调用一.简介 一般需要引入一个独立页面的时候,我们会使用iframe.在业务需要的时候,我们需要在父页面与iframe页面之间进行交互.交互的时候,我们就需要使 用到 ...
- 两个APP之间怎么调用《IT蓝豹》
两个app之间怎么调用? (1):通过显示Intent 启动 首先:配置好B app 的action,即AndroidManifest.xml中声明 <intent-filter> ...
- 《同一个类中不同方法之间的调用相关问题(省略的类名或者this)》
//同一个类中不同方法之间的调用相关问题(省略的类名或者this) class A { public void B() { System.out.println("b方法运行"); ...
- JAVA 构造方法之间的调用
this:看上去,用来区分局部变量和成员变量的情况this:就是代表本类对象,this代表它所在方法所属对象的引用构造方法之间的调用只能通过this语句来完成构造方法之间进行调用时this语句只能出现 ...
- Iframe父页面与子页面之间的调用
原文:Iframe父页面与子页面之间的调用 Iframe父页面与子页面之间的调用 专业词语解释如下: Iframe:iframe元素是文档中的文档. window对象: 浏览器会在其打 ...
- 使用DLL进行不同语言之间的调用(转)
源:使用DLL进行不同语言之间的调用 __declspec(dllexport) 是告诉编译器用来导出函数的,在代码中不另作说明了. extern "C" 的意思就是用C的方式来导 ...
- synchronized修饰的方法之间相互调用
1:synchronized修饰的方法之间相互调用,执行结果为There hello ..因为两个方法(main,hello)的synchronized形成了互斥锁. 所以当main方法执行完之后 ...
- 对于应用之间的调用,如何选择rpc还是mq?
两个系统之间的调用,是选择rpc呢还是mq,说一下你们系统的选择吧 比如rpc可以是简单的spring httpinvoker,但是前提是都是java应用而且都是用spring framework,可 ...
- Java基础21-构造函数之间的调用
public class Test{ public static void main(String[] args){ Persion p2=new Persion("小明",22) ...
随机推荐
- 网络安全(中职组)-B模块:暴力破解
任务环境说明: 服务器场景名称:sql008 服务器场景用户名:administrator:密码:未知(封闭靶机) 1.使用渗透机场景kali中工具扫描服务器场景,将iis的版本号作为flag提交: ...
- 验证码案例的实现---MyBatis+Session+Cookie
展示验证码(jsp页面) 首先,我们需要自己利用BufferedImage类去生成一张可以变换的验证码图片: 之后,我们就可以利用这样一串代码去将验证码里面的内容获取到: 这是一串测试代码: Outp ...
- 人脸关键点的应用场景及重难点解析丨Dev for Dev 专栏
本文为「Dev for Dev 专栏」系列内容,作者为声网视频组 AI 算法工程师 周世付. 人脸检测.人脸关键点检测,是计算机视觉的基础算法.许多酷炫应用背后,例如美颜.贴纸.人脸驱动 avatar ...
- day08-自定义转换器&处理JSON&内容协商
自定义转换器&处理JSON&内容协商 1.自定义转换器 1.1基本介绍 SpringBoot 在响应客户端请求时,将提交的数据封装成对象时,使用了内置的转换器,也就是自动帮我们封装对象 ...
- 机器学习基础05DAY
分类算法之k-近邻 k-近邻算法采用测量不同特征值之间的距离来进行分类 优点:精度高.对异常值不敏感.无数据输入假定 缺点:计算复杂度高.空间复杂度高 使用数据范围:数值型和标称型 一个例子弄懂k-近 ...
- 温故知新----线程之Runnable与Callable接口的本质区别
温故知新----线程之Runnable与Callable接口的本质区别 预备知识:Java中的线程对象是Thread,新建线程也只有通过创建Thread对象的实例来创建. 先说结论 1 Runnabl ...
- 使用webpack 优化自己的项目。
一.首先要了解概念:module,chunk 和 bundle 到底是什么? module,chunk 和 bundle 其实就是同一份逻辑代码在不同转换场景下的取了三个名字: 我们直接写出来的是 m ...
- 几个对js帮助挺多的大佬写的博客
深入理解javascript原型和闭包(完结) JavaScript系列文章 同步异步回调DEMO知乎大佬的this与new解释 宏任务与微任务解析 js闭包 Vue项目中技巧ts学习 ES6基础入门 ...
- 红队实战靶场ATT&CK(二)
一.环境配置 web靶机有一块NAT网卡,只需要修改这块NAT网卡的网关,IP改成与攻击机器同网段就可以了 到web靶机中C:/Oracle/Middleware/user_projects/doma ...
- 在Mac搭建一个便捷的Markdown创作环境
前言 使用 Typora + PicGo + Gitee + Snipaste 在 Mac 搭建一个 Markdown 编辑环境. Typora 是一款简洁的 Markdown 编辑器: PicGo ...