linux内核模块符号导出

news2024/10/6 10:39:13

一、内核模块符号导出简介

  驱动程序编译生成的 ko 文件是相互独立的,即模块之间变量或者函数在正常情况下无法进行互相访问。而一些复杂的驱动模块需要分层进行设计,这时候就需要用到内核模块符号导出。
  内核符号导出指的是在内核模块中导出相应的函数和变量,在加载模块时被记录在公共内核符号表中,以供其他模块调用。符号导出所使用的宏为 EXPORT_SYMBOL(sym)和 EXPORT_SYMBOL_GPL(sym)。它们定义在 “/include/linux/export.h”文件中。

#define EXPORT_SYMBOL(sym) \ 
	__EXPORT_SYMBOL(sym, "")
#define EXPORT_SYMBOL_GPL(sym) \ 
	__EXPORT_SYMBOL(sym, "_gpl")

  EXPORT_SYMBOL(sym)和 EXPORT_SYMBOL_GPL(sym)两个宏使用方法相同,而 EXPORT_SYMBOL_GPL(sym)导出的模块只能被 GPL 许可的模块使用,所以绝大多数的情况都使用EXPORT_SYMBOL(sym)进行符号导出。sym 为函数的唯一参数,表示要导出的函数或变量名称。

二、应用实例

  总共有两个驱动程序,第一个驱动文件名为 mathmodule.c,用来定义参数 num 和函数 add(a,b),第二个驱动文件名为 hello.c, 会引用 mathmodule.c 驱动程序中的参数 num 和数学函数 add(a,b),并将相应的参数值和函数返回值打印到串口终端上。

2.1、mathmodule.c 代码

  mathmodule.c 代码如下

#include <linux/init.h>
#include <linux/module.h>
int num = 10;//定义参数num
EXPORT_SYMBOL(num);//导出参数num

int add(int a, int b)//定义数学函数add(),用来实现加法
{
    return a + b;
}
EXPORT_SYMBOL(add);//导出数学函数add()

static int __init math_init(void)//驱动入口函数
{
    printk("math_moudle init\n");
    return 0;
}

static void __exit math_exit(void)//驱动出口函数
{
    printk("math_module exit\n");
}

module_init(math_init);//注册入口函数
module_exit(math_exit);//注册出口函数

  以上代码定义了一个 int 类型的 num 变量和 add()数学函数,并使用 EXPORT_SYMBOL 宏进行导出。

2.2、hello.c 代码

  编写完成的 hello.c 代码如下

#include <linux/init.h>
#include <linux/module.h>
extern int num;//导入int类型变量num
extern int add(int a, int b);//导入函数add
static int __init hello_init(void)//驱动入口函数
{
    static int sum;
    printk("num = %d\n", num);//打印num值
    sum = add(3, 4);//使用add函数进行3+4的运算                                                                                                                                                                          
    printk("sum = %d\n", sum);//打印add函数的运算值
    return 0;
}

static void __exit hello_exit(void)//驱动出口函数
{
    printk("Goodbye hello module\n");
}

module_init(hello_init);//注册入口函数
module_exit(hello_exit);//注册出口函数

  程序导入了 int 类型的变量 num 和 add()函数,并在驱动入口函数中打印相应了 num 的参数值并对 add()函数进行了调用。

2.3、makefile文件

  在 mathmodule.c 和 hello.c 的同一目录下创建 Makefile 文件,Makefile 文件内容如下

export ARCH=arm64#设置平台架构
export CROSS_COMPILE=aarch64-linux-gnu-#交叉编译器前缀
obj-m := mathmodule.o
obj-m += hello.o
KDIR :=/home/topeet/Linux/linux_sdk/kernel    #这里是你的内核目录                                                                                                                            
PWD ?= $(shell pwd)
all:
	make -C $(KDIR) M=$(PWD) modules    #make操作
clean:
	make -C $(KDIR) M=$(PWD) clean    #make clean操作

  在 hello.c 代码中使用了mathmodule.c 所导出的符号,所以 mathmodule.c 要在 hello.c 之前进行编译,即第 3 行和第 4行顺序不能交换

2.4、运行测试

  这里要注意的是,由于 hello.ko 依赖于 mathmodule.ko,所以 mathmodule.ko 需要先加载,
  分别使用以下命令进行模块的加载(加载顺序不能变)

insmod mathmodule.ko
insmod hello.k

在这里插入图片描述
  可以看到 hello.ko 驱动加载的时候,mathmodule.ko 模块中定义的 num 参数值和调用 sum()函数的后正确的返回值都被打印了出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1106829.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[MAUI]深入了解.NET MAUI Blazor与Vue的混合开发

文章目录 Vue在混合开发中的特点创建MAUI项目创建Vue应用使用element-ui组件库JavaScript和原生代码的交互传递根组件参数从设备调用Javascript代码从Vue页面调用原生代码 读取设备信息项目地址 .NET MAUI结合Vue的混合开发可以使用更加熟悉的Vue的语法代替Blazor语法&#xff…

Cypress安装使用

node.js 安装使用Cypress总是会看见node.js&#xff0c;那就先看看node.js是什么。JavaScript以前运行需要在浏览器中&#xff08;浏览器内置解释器&#xff09;&#xff0c;通过node.js框架内置v8引擎&#xff08;也就是可以执行js脚本所需的工具&#xff09;&#xff0c;这样…

金翅擘海|人大女王金融硕士庞雪雨:行学之道,在自律、在勤勉、在止于至善

庞雪雨 中国人民大学-加拿大女王大学金融硕士2022-2023级行业高管班 光大保德信资产管理有限公司董事总经理 当我进入到人大校园的那一刻&#xff0c;映入眼帘的是明德楼&#xff0c;由此我想到了《大学》&#xff0c;大学开篇中讲到&#xff0c;大学之道&#xff0c;在明明德&…

如何理解Linux字符设备驱动?

我们学习编程的时候&#xff0c;一般都会从hello程序开始。同样的&#xff0c;学习Linux驱动&#xff0c;我们也是从最简单的hello驱动学起。 一、驱动层和应用层 看一下STM32裸机开发与嵌入式Linux开发的一些区别&#xff1a; 嵌入式Linux的开发方式与STM32裸机开发的方式有…

【数值分析】1 - 误差及有关概念

文章目录 一、误差的背景介绍1.1 误差的来源与分类1.2 误差的传播与积累1.3 例题1.3.1 公式一1.3.2 公式二1.3.3 总结 二、误差与有效数字2.1 绝对误差与绝对误差限2.2 相对误差和相对误差限 三、有效数字3.1 有效数字的定义和标准浮点式3.1.1 例题 3.2 有效数字与相对误差的关…

【一文清晰】单元测试到底是什么?应该怎么做?

我是java程序员出身&#xff0c;后来因为工作原因转到到了测试开发岗位。测试开发工作很多年后&#xff0c;现在是一名自由职业者 1、什么是单元测试 2、该怎么做单元测试 一、什么是单元测试&#xff1f; 单元测试&#xff08;unit testing&#xff09;&#xff0c;是指对软件…

4款文件恢复工具推荐,恢复数据就靠它们!

“想问问大家在使用电脑时有什么好的文件恢复工具推荐吗&#xff1f;最近好像有点粗心&#xff0c;经常误删文件&#xff0c;非常需要一个有用的恢复工具&#xff0c;希望大家给些意见&#xff01;” 在日常工作或学习中&#xff0c;由于各种原因造成的文件丢失是很正常的情况。…

什么是模拟芯片,模拟芯片都有哪些测试指标?

模拟芯片又称处理模拟信号的集成电路 模拟集成电路主要是指由电容、电阻、晶体管等组成的模拟电路集成在一起用来处理模拟信号的集成电路。有许多的模拟集成电路&#xff0c;如运算放大器、模拟乘法器、锁相环、电源管理芯片等。 模拟集成电路的主要构成电路有&#xff1a;放…

打造属于自己的vue图标库

hfex-icon图标库 Install npm i -D hfex-icon主要提供2种使用方式 方式一 通过svg图标资源&#xff0c;借助unplugin-icons库将svg图标文件生成vue组件&#xff0c;然后通过vue组件的引入方式在vue中使用 unplugin-icons 兼容vue2和vue3 在vue.config.js的plugins中配置…

“轻松实现文件夹批量重命名:使用顺序编号批量改名“

你是否曾经需要大量修改文件夹名称&#xff1f;或者需要为文件夹添加有序编号以便于管理&#xff1f;下面就教你一个简单的方法&#xff0c;轻松实现文件夹批量重命名&#xff0c;使用顺序编号批量改名。 首先我们要进入文件批量改名高手主页面&#xff0c;并在板块栏里选择“文…

java springboot VUE粮食经销系统开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 springboot VUE 粮食经销系统是一套完善的完整信息管理类型系统&#xff0c;结合springboot框架和VUE完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用springboot框架&#xff08;MVC模式开发&#xff09; &#xff0c;系统具有完整的源代码和数…

kafka、zookeeper、flink测试环境、docker

1、kafka环境单点 根据官网版本说明(3.6.0)发布&#xff0c;zookeeper依旧在使用状态&#xff0c;预期在4.0.0大版本的时候彻底抛弃zookeeper使用KRaft(Apache Kafka)官方并给出了zk迁移KR的文档 2、使用docker启动单点kafka 1、首先将kafka启动命令&#xff0c;存储为.servi…

LLC 三相移相PWM产生原理分析

LLC 三相移相PWM产生原理分析 void MX_PWM_Stop(void) {//----------------------使用停止函数后会导致移相角度为60度---------------------------------------------------------------- #if 1 //------Tim1 PWM定时器初始化------------------ HAL_TIM_OC_Stop(&htim1…

最新Google play开发者账号注册要求、单位账号邓白氏编码问题及身份验证解决思路!

随着Google play商店的蓬勃发展&#xff0c;越来越多的开发者在上面上传应用&#xff0c;但部分开发者为了获得更多的收益&#xff0c;试图通过多种方式绕过谷歌限制&#xff0c;无视谷歌规则。 为了维持Google play的生态环境&#xff0c;谷歌采取了多种方式和方法去应对这些…

决策树oo

决策树学习的算法通常是一个递归地选择最优特征(选择方法的不同&#xff0c;对应着不同的算法)&#xff0c;并根据该特征对训练数据进行分割&#xff0c;使得各个子数据集有一个最好的分类的过程。这一过程对应着对特征空间的划分&#xff0c;也对应着决策树的构建 步骤&#…

git切换远程仓库源步骤

git切换远程仓库源步骤&#xff1a; 第一步&#xff1a;git remote -v 查看当前远程仓库源&#xff1a; 第二步&#xff1a;git remote rm origin删除远程仓库源&#xff1b; 第三步&#xff1a;git remote add origin http://newURL.git 添加新的远程仓库源地址&#xff1b…

Operator 开发实践 四 (WebHook)

1. WebHook介绍 我们知道访问Kubernetes API有好几种方式&#xff0c;比如使用kubectl命令、使用client-go之类的开发库、直接通过REST请求等。不管是一个使用kubectl的真人用户&#xff0c;还是一个Service Account&#xff0c;都可以通过API访问认证&#xff0c;这个过程官网…

AI机器视觉多场景应用迸发检测活力,引领食品及包装行业新发展

随着食品安全意识的广泛传播&#xff0c;人们对食品质量和安全的要求越来越高&#xff0c;众多食品包装厂商加速产线数智化转型&#xff0c;迫切需要高效、准确且智能化的检测技术。 在现代食品及包装行业的自动化生产中&#xff0c;涉及到各种各样的识别、检测、测量等环节&a…

LabVIEW中管理大型数据

LabVIEW中管理大数据 LabVIEW的最大优势之一是自动内存管理。这种内存管理允许用户轻松创建字符串、数组和集群&#xff0c;而无需C/C用户经常担心。但是&#xff0c;这种内存管理设计为绝对安全&#xff0c;因此数据被非常频繁地复制。这通常不会造成任何问题&#xff0c;但是…

Linux下使用openssl制作证书

openssl是一个功能丰富且自包含的开源安全工具箱。它提供的主要功能有&#xff1a;SSL协议实现(包括SSLv2、SSLv3和TLSv1)、大量软算法(对称/非对称/摘要)、大数运算、非对称算法密钥生成、ASN.1编解码库、证书请求(PKCS10)编解码、数字证书编解码、CRL编解码、OCSP协议、数字证…