驱动学习(三)符号导出

1.什么是符号?
主要是指全局变量和函数

2.为什么要导出符号?
​ linux内核采用的是模块化的形式管理内核代码。内核中每个模块之间是相互独立的,也就是说A模块的全局变量和函数,B模块是无法访问的。若B模块想要使用A模块中的已有符号,那么必须将A模块中的符号做符号导出,导出到模块符号表中,然后B模块可以使用A模块导出的符号。

3.如何导出符号?
​ linux内核给我们提供了两个函数宏,用他们做符号导出。

3.1 EXPORT_SYMBOL(符号)
3.2 EXPORT_SYMBOL_GPL(符号)

4.符号表的类型
4.1 本地符号表
用户自定义模块导出的符号表,这些符号表保存在本模块目录下Module.symvers

4.2 全局符号表
内核已经导出的符号表,在 /proc/kallsyms

​ sudo cat /proc/kallsyms |grep printk 0xc15cd833

5.注意
安装时,先安装符号导出模块,再安装使用符号的模块;
卸载时,先卸载使用符号的模块,再卸载导出符号的模块。

6.测试
6.1 测试思路
分别创建两个驱动模块文件夹,分别编写符号导出驱动模块(helloa.c)和符号使用驱动模块(hellob.c)。

在helloa.c中使用EXPORT_SYMBOL()宏函数和EXPORT_SYMPOL_GPL()宏函数测试导出符号。

编译helloa.c会生成本地符号表Module.symvers。

将生成的本地符号表Module.symvers拷贝到hellob驱动模块文件夹下,编译hellob.c。

查看内核打印消息

验证对错

6.2 本地符号表符号导出实际操作
创建文件夹,每个文件夹下有一个.c源码和Makefile工程管理文件

helloa.c

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

int num = 100;
void show(void)
{
        printk("aaaa:  num =%d \n",num);
}
static int hello_init(void)
{
        printk("hello_init \n");
        return 0;
}
static void hello_exit(void)
{
        printk("hello_exit \n");
        return;
}
EXPORT_SYMBOL(num);
EXPORT_SYMBOL(show);
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("cfy");


Makefile

ifneq ($(KERNELRELEASE),)
$(info "2nd")
obj-m:=helloa.o
else
KDIR :=/lib/modules/$(shell uname -r)/build
PWD  :=$(shell pwd)
all:
        $(info "1st")
        make -C $(KDIR) M=$(PWD) modules
endif

clean:
        rm -f *.ko *.o *.mod.o *.symvers *.cmd  *.mod.c *.order

Makefile

ifneq ($(KERNELRELEASE),)
$(info "2nd")
obj-m:=helloa.o
else
KDIR :=/lib/modules/$(shell uname -r)/build
PWD  :=$(shell pwd)
all:
        $(info "1st")
        make -C $(KDIR) M=$(PWD) modules
endi

clean:
        rm -f *.ko *.o *.mod.o *.symvers *.cmd  *.mod.c *.order


​ hellob.c

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

extern int num;
extern  void show(void);
static int hello_init(void)
{
        printk("hello_init %d\n",num);
        show();
        return 0;
}
static void hello_exit(void)
{
        printk("hello_exit \n");
        return;
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("cfy");

 Makefile

ifneq ($(KERNELRELEASE),)
$(info "2nd")
obj-m:=hellob.o
else
KDIR :=/lib/modules/$(shell uname -r)/build
PWD  :=$(shell pwd)
KBUILD_EXTRA_SYMBOLS += /home/lwj/driver/code-final/02export/a/Module.symvers
all:
        $(info "1st")
        make -C $(KDIR) M=$(PWD) modules
endif

clean:
        rm -f *.ko *.o *.mod.o *.symvers *.cmd  *.mod.c *.order

编译helloa.c


生成Module.symvers


将Module.symvers拷贝到b下

编译hellob.c,出现了未定义的问题。

参考https://blog.csdn.net/a834605978/article/details/125648701,找到了解决方法

修改hellob的Makefile,添加了第10行,注意要在make modules命令之后加载,一开始在之前加载,发现问题依然存在

ifneq ($(KERNELRELEASE),)
$(info "2nd")
obj-m:=hellob.o
else
KDIR :=/lib/modules/$(shell uname -r)/build
PWD  :=$(shell pwd)
KBUILD_EXTRA_SYMBOLS += /home/lwj/driver/code-final/02export/a/Module.symvers
all:
        $(info "1st")
        make -C $(KDIR) M=$(PWD) modules
endif

KBUILD_EXTRA_SYMBOLS += /home/lwj/driver/code-final/02export/a/Module.symvers

clean:
        rm -f *.ko *.o *.mod.o *.symvers *.cmd  *.mod.c *.order


重新编译

安装导出模块

可以看到驱动模块可以正常安装,dmesg有打印信息

安装hellob模块

可以看到hellob驱动模块已经成功加载了helloa驱动模块中的全局变量num和全局函数show
                      

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python爬虫——Selenium的基本使用

目录 一、Selenium的介绍 二、环境准备 1.安装Selenium 2.安装WebDriver 三、元素定位 1.常用定位元素的方法 2. 通过指定方式定位元素 四、窗口操作 1.最大化浏览器窗口 2.设置浏览器窗口大小 3.切换窗口或标签页 切换回主窗口 4. 关闭窗口 关闭当前窗口 关闭所…

java_方法重载、可变参数、作用域

方法重载 基本介绍 java 中允许同一个类中&#xff0c;多个同名方法的存在&#xff0c;但要求 形参列表不一致&#xff01; 比如&#xff1a;System.out.println(); out 是 PrintStream 类型 重载的好处 减轻了起名的麻烦减轻了记名的麻烦 案例 public class OverLoad01 …

SCI一区级 | Matlab实现SSA-TCN-LSTM-Attention多变量时间序列预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.基于SSA-TCN-LSTM-Attention麻雀搜索算法优化时间卷积长短期记忆神经网络融合注意力机制多变量时间序列预测&#xff0c;要求Matlab2023版以上&#xff0c;自注意力机制&#xff0c;一键单头注意力机制替换成多头注…

leetcode刷题(76-80)

算法是码农的基本功&#xff0c;也是各个大厂必考察的重点&#xff0c;让我们一起坚持写题吧。 遇事不决&#xff0c;可问春风&#xff0c;春风不语&#xff0c;即是本心。 我们在我们能力范围内&#xff0c;做好我们该做的事&#xff0c;然后相信一切都事最好的安排就可以啦…

深度生成模型 - 受限玻尔兹曼机(RBM)篇

前言 受限玻尔兹曼机&#xff08; Restricted Boltzmann Machine&#xff0c;RBM \text{Restricted Boltzmann Machine&#xff0c;RBM} Restricted Boltzmann Machine&#xff0c;RBM&#xff09;是深度学习领域中的一种重要模型&#xff0c;其起源于统计物理学&#xff0c;由…

【再谈设计模式】单例模式~唯一性的守护者

一、引言 在软件工程中&#xff0c;软件开发&#xff0c;设计模式是提高代码复用性和可维护性的有效工具。单例模式&#xff08;Singleton Pattern&#xff09;作为一种创建型设计模式&#xff0c;旨在确保一个类只有一个实例&#xff0c;并提供对该实例的全局访问。这一模式在…

如何在 Elasticsearch Ruby 客户端中使用 ES|QL Helper

作者&#xff1a;来自 Elastic Fernando Briano 了解如何使用 Elasticsearch Ruby 客户端编写 ES|QL 查询并处理其结果。 简介 Elasticsearch Ruby 客户端可用于编写 EQ|QL 查询&#xff0c;使处理从 esql.query 返回的数据更加容易。ES|QL 允许开发人员通过查询过滤、转换和分…

redis详细教程(3.ZSet,Bitmap,HyperLogLog)

ZSet Redis 的 ZSet&#xff08;有序集合&#xff09;是一种特殊的数据类型&#xff0c;它允许存储一系列不重复的字符串元素&#xff0c;并为每个元素关联一个分数&#xff08;score&#xff09;。这个分数用于对集合中的元素进行排序。ZSet 的特点是&#xff1a; 唯一性&am…

MYSQL-SQL-03-DQL(Data Query Language,数据查询语言)(单表查询)

DQL&#xff08;数据查询语言&#xff09; DQL英文全称是Data Query Language(数据查询语言)&#xff0c;数据查询语言&#xff0c;用来查询数据库中表的记录。 查询关键字: SELECT 在一个正常的业务系统中&#xff0c;查询操作的频次是要远高于增删改的&#xff0c;当我们去访…

Cisco Packet Tracer 8.0 路由器的基本配置和Telnet设置

文章目录 构建拓扑图配置IP地址配置路由器命令说明测试效果 构建拓扑图 1&#xff0c;添加2811路由器。 2&#xff0c;添加pc0。 3&#xff0c;使用交叉线连接路由器和pc&#xff08;注意线路端口&#xff09;。 4&#xff0c;使用配置线连接路由器和pc&#xff08;注意线路…

优化网站结构提升用户体验的关键要素

内容概要 在数字时代&#xff0c;网站的架构和用户体验密切相关。一个合理的网站结构不仅能帮助用户快速找到所需信息&#xff0c;还能提升整体的访问满意度。为了达到这一目的&#xff0c;网站需要强调几个关键要素。 首先&#xff0c;清晰的导航设计至关重要。导航应当直观…

Android Gradle

#1024程序员节&#xff5c;征文# Gradle 是一款强大的自动化构建工具&#xff0c;广泛应用于 Android 应用开发。它通过灵活的配置和丰富的插件系统&#xff0c;为项目构建提供了极大的便利。本文只是简单的介绍 Gradle 在 Android 开发中的使用&#xff0c;包括其核心概念、构…

微积分复习笔记 Calculus Volume 1 - 3.8 Implicit Differentiation

3.8 Implicit Differentiation - Calculus Volume 1 | OpenStax

Java——lambda表达式和StreamAPI

一、lambda 1. lambda表达式 1.1 Lambda表达式的使用举例: (o1,02)->Integer.compare(o1,o2); 1.2 Lambda表达式的格式举例: Lambda形参列表->lambda 1.3 Lambda表达式的格式 lambda操作符或箭头操作符 的左边:lambda形参列表&#xff0c;对应着要重写的接口中的…

django游戏门户系统

想做毕业设计但还没有头绪&#xff1f;&#x1f64b;‍♂️django游戏门户系统了解一下&#xff01;这个系统不仅功能全面&#xff0c;还能轻松解决你的项目选题难题&#xff01; 我们这个基于Django开发的游戏门户系统提供了用户注册、登录、内容发布以及管理功能&#xff0c…

大数据日志处理框架ELK方案

介绍应用场景大数据ELK日志框架安装部署 一&#xff0c;介绍 大数据日志处理框架ELK&#xff08;Elasticsearch、Logstash、Kibana&#xff09;是一套完整的日志集中处理方案&#xff0c;以下是对其的详细介绍&#xff1a; 一、Elasticsearch&#xff08;ES&#xff09; 基本…

【SQL实验】表的更新和简单查询

完整代码在文章末尾 在上次实验创建的educ数据库基础上&#xff0c;用SQL语句为student表、course表和sc表中添加以下记录 【SQL实验】数据库、表、模式的SQL语句操作_创建一个名为educ数据库,要求如下: (下面三个表中属性的数据类型需要自己设计合适-CSDN博客在这篇博文中已经…

LeetCode反转链表

题目描述 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 示例 2&#xff1a; 输入&#xff1a;head [1,2] 输出&#xff1a;[2,1] 示例 3&#…

011:软件卸载工具TotalUninstall安装教程

摘要&#xff1a;本文详细介绍软件卸载工具TotalUninstall安装流程。 一、软件介绍 TotalUninstall是一款功能强大的卸载与清理工具&#xff0c;它能够彻底卸载不需要的应用程序&#xff0c;并清除相关的注册表项、文件残留和临时文件&#xff0c;确保系统干净无残留&#xff…

美畅物联丨视频上云网关如何配置上级联网云平台

在当今的智慧交通与安防监控体系中&#xff0c;视频上云网关发挥着至关重要的作用。以美畅视频上云网关为例&#xff0c;具备强大的兼容性&#xff0c;能够对接来自不同厂家、不同型号的视频设备&#xff0c;将这些设备输出的各异视频流进行汇聚整合。在获取摄像机视频流后&…