linux内核模块编译方法之模块编程详解

news2025/3/1 19:24:22

文章目录

  • 一、模块传参
  • 二、模块依赖
  • 三、内核空间和用户空间
  • 四、执行流
  • 五、模块编程与应用编程的比较
  • 六、内核接口头文件查询
  • 总结


本期和大家主要分享的是驱动开发内核编译过程中对于模块是如何设计的,进行了详细的分享,从模块传参、模块依赖一直到内核空间用户空间以及模块编程和应用编程的比较,希望各位小伙伴能够把这些基础的知识点掌握好,为今后成功进阶为优秀的驱动开发工程师打好基础!

一、模块传参

module_param(name,type,perm);//将指定的全局变量设置成模块参数
/*
name:全局变量名
type:
    使用符号      实际类型                传参方式
	bool	     bool           insmod xxx.ko  变量名=0 或 1
	invbool      bool           insmod xxx.ko  变量名=0 或 1
	charp        char *         insmod xxx.ko  变量名="字符串内容"
	short        short          insmod xxx.ko  变量名=数值
	int          int            insmod xxx.ko  变量名=数值
	long         long           insmod xxx.ko  变量名=数值
	ushort       unsigned short insmod xxx.ko  变量名=数值
	uint         unsigned int   insmod xxx.ko  变量名=数值
	ulong        unsigned long  insmod xxx.ko  变量名=数值
perm:给对应文件 /sys/module/name/parameters/变量名 指定操作权限
	#define S_IRWXU 00700
	#define S_IRUSR 00400
	#define S_IWUSR 00200
	#define S_IXUSR 00100
	#define S_IRWXG 00070
	#define S_IRGRP 00040
	#define S_IWGRP 00020
	#define S_IXGRP 00010
	#define S_IRWXO 00007
	#define S_IROTH 00004
	#define S_IWOTH 00002  //不要用 编译出错
	#define S_IXOTH 00001
*/
module_param_array(name,type,&num,perm);
/*
name、type、perm同module_param,type指数组中元素的类型
&num:存放数组大小变量的地址,可以填NULL(确保传参个数不越界)
    传参方式 insmod xxx.ko  数组名=元素值0,元素值1,...元素值num-1  
*/

可用MODULE_PARAM_DESC宏对每个参数进行作用描述,用法:

MODULE_PARM_DESC(变量名,字符串常量);

字符串常量的内容用来描述对应参数的作用

modinfo可查看这些参数的描述信息

下面给出一个关于模块传参的例子:

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

int gx = 10;
char *gstr = "hello";
int garr[5] = {1,2,3,4,5};

/* 添加模块参数 */
module_param(gx, int, 0664);
module_param(gstr, charp, 0664);
module_param_array(garr, int, NULL, 0664);

int __init myhello_init(void)
{
	int i = 0;

	printk("gx = %d\n", gx);
	printk("gstr = %s\n", gstr);
	for(i = 0;i < 5;++i)
	{
		printk("garr[%d] = %d\n", i, garr[i]);
	}
	return 0;
}

void __exit myhello_exit(void)
{
	printk("myhello bye bye!!!\n");
}


MODULE_LICENSE("GPL");

module_init(myhello_init);
module_exit(myhello_exit);

那么程序运行的结果如下:
在这里插入图片描述
这里还可以进行下列方式的参数传递:

sudo insmod ./testparam.ko gx=400 gstr=“nihao” garr=4,5,6,7,8

在这里插入图片描述
这里能发现的结论是当字符串中间出现空格的时候,会对赋值进行打断,最终输入的有效字符串仅为空格前面的部分!

二、模块依赖

​ 既然内核模块的代码与其它内核代码共用统一的运行环境,也就是说模块只是存在形式上独立,运行上其实和内核其它源码是一个整体,它们隶属于同一个程序,因此一个模块或内核其它部分源码应该可以使用另一个模块的一些全局特性。

一个模块中这些可以被其它地方使用的名称被称为导出符号,所有导出符号被填在同一个表中这个表被称为符号表。

最常用的可导出全局特性为全局变量和函数

查看符号表的命令:nm
nm查看elf格式的可执行文件或目标文件中包含的符号表,用法:

nm 文件名 (可以通过man nm查看一些字母含义)

两个用于导出模块中符号名称的宏:

EXPORT_SYMBOL(函数名或全局变量名)
EXPORT_SYMBOL_GPL(函数名或全局变量名) 需要GPL许可证协议验证

使用导出符号的地方,需要对这些符号进行extern声明后才能使用这些符号

B模块使用了A模块导出的符号,此时称B模块依赖于A模块,则:

  1. 编译次序:先编译模块A,再编译模块B,当两个模块源码在不同目录时,需要:i. 先编译导出符号的模块A ii. 拷贝A模块目录中的Module.symvers到B模块目录 iii. 编译使用符号的模块B。否则编译B模块时有符号未定义错误
  2. 加载次序:先插入A模块,再插入B模块,否则B模块插入失败
  3. 卸载次序:先卸载B模块,在卸载A模块,否则A模块卸载失败

补充说明:
内核符号表(直接当文本文件查看)
/proc/kallsyms运行时 /boot/System.map编译后

三、内核空间和用户空间

为了彻底解决一个应用程序出错不影响系统和其它app的运行,操作系统给每个app一个独立的假想的地址空间,这个假想的地址空间被称为虚拟地址空间(也叫逻辑地址),操作系统也占用其中固定的一部分,32位Linux的虚拟地址空间大小为4G,并将其划分两部分:

  1. 0~3G 用户空间 :每个应用程序只能使用自己的这份虚拟地址空间

  2. 3G~4G 内核空间:内核使用的虚拟地址空间,应用程序不能直接使用这份地址空间,但可以通过一些系统调用函数与其中的某些空间进行数据通信

实际内存操作时,需要将虚拟地址映射到实际内存的物理地址,然后才进行实际的内存读写

四、执行流

执行流:有开始有结束总体顺序执行的一段独立代码,又被称为代码上下文

计算机系统中的执行流的分类:

执行流:

  1. 任务流–任务上下文(都参与CPU时间片轮转,都有任务五状态:就绪态 运行态 睡眠态 僵死态 暂停态)
    1. 进程
    2. 线程
      1. 内核线程:内核创建的线程
      2. 应用线程:应用进程创建的线程
  2. 异常流–异常上下文
    1. 中断
    2. 其它异常

应用编程可能涉及到的执行流:

  1. 进程
  2. 线程

内核编程可能涉及到的执行流:

  1. 应用程序自身代码运行在用户空间,处于用户态 ----------------- 用户态app
  2. 应用程序正在调用系统调用函数,运行在内核空间,处于内核态,即代码是内核代码但处于应用执行流(即属于一个应用进程或应用线程) ---- 内核态app
  3. 一直运行于内核空间,处于内核态,属于内核内的任务上下文 --------- 内核线程
  4. 一直运行于内核空间,处于内核态,专门用来处理各种异常 --------- 异常上下文

五、模块编程与应用编程的比较

不同点内核模块应用程序
API来源不能使用任何库函数各种库函数均可以使用
运行空间内核空间用户空间
运行权限特权模式运行非特权模式运行
编译方式静态编译进内核镜像或编译特殊的ko文件elf格式的应用程序可执行文件
运行方式模块中的函数在需要时被动调用从main开始顺序执行
入口函数init_modulemain
退出方式cleanup_modulemain函数返回或调用exit
浮点支持一般不涉及浮点运算,因此printk不支持浮点数据支持浮点运算,printf可以打印浮点数据
并发考虑需要考虑多种执行流并发的竞态情况只需考虑多任务并行的竞态
程序出错可能会导致整个系统崩溃只会让自己崩溃

六、内核接口头文件查询

大部分API函数包含的头文件在include/linux目录下,因此:

  1. 首先在include/linux 查询指定函数:grep 名称 ./ -r -n
  2. 找不到则更大范围的include目录下查询,命令同上
    给出一个例子:查找atomic_set对应的头文件
    在这里插入图片描述
    表示头文件为<sam/atomic.h>

总结

本期主要分享的是关于驱动开发过程中一些基础必备的知识点,除过基本的知识点,还有一些常用操作,掌握了这些能够帮助我们提升工作效率,希望大家都联练习起来,学以致用!!!
最后,各位小伙伴们如果喜欢我的分享可以点赞收藏哦,你们的认可是我创作的动力,一起加油!

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

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

相关文章

楼顶空地适合建造气膜体育馆吗?

众所周知&#xff0c;传统建筑的荷载太大&#xff0c;出于安全考虑&#xff0c;是不适合继续在楼顶加盖传统结构体育馆的&#xff0c;但是&#xff0c;气膜体育馆作为一种装配式建筑&#xff0c;它是可以在城市高空上建造一个轻盈又新颖独特的全天候气膜馆。 气膜体育馆作为一种…

小黑自己在家尝试涮牛排,肚子又开始了新一轮的胀气,喝到了酱香拿铁并烫了纹理发型体验一把的leetcode之旅:123. 买卖股票的最佳时机 III

动态规划1 class Solution:def maxProfit(self, prices: List[int]) -> int:# 数组长度n len(prices)if n < 2:return 0# 动态规划变量# 第一次买的价格first_price prices[0]# 第一次卖的收益first_cell 0# 第二次买的价格second_price prices[0]# 第二次卖second_…

STM32H750 HAL CUBEMX 时钟失败及死机无法下载问题解决

芯片采样电压设置&#xff0c;否则 无法运行 解决死机问题 设置swd 模式 短接 boot0 —vcc 3.3v即可正常下载

驱动开发,stm32mp157a开发板的led灯控制实验

1.实验目的 编写LED灯的驱动&#xff0c;在应用程序中编写控制LED灯亮灭的代码逻辑实现LED灯功能的控制&#xff1b; 2.LED灯相关寄存器分析 LED1->PE10 LED1亮灭&#xff1a; RCC寄存器[4]->1 0X50000A28 GPIOE_MODER[21:20]->01 (输出) 0X50006000 GPIOE_ODR[10]-&g…

5. HBase必知必会之理论进阶篇

HBase必知必会之理论进阶篇 1.1 集群搭建以及规模预测1.1.1 HBase集群搭建1.1.2 HBase集群规划 1.2 HBase重要的概念1.2.1 snapshot1.2.2 region 切分1.2.3 RIT1.2.4 HBase读优化1.2.4.1 客户端优化1.2.4.2 服务端优化1.2.4.3 hdfs 优化 1.2.5 HBase写优化1.2.5.1 客户端优化1.…

Linux centos7 bash编程训练__打印各类形状

利用for循环&#xff0c;打印各种不同的三角形、矩形和菱形。 主要是fort循环嵌套使用&#xff0c;及条件判断等。 因方法简单&#xff0c;不作更多解释&#xff0c;部分注释可以帮助初学者掌握代码。 下面列出代码&#xff0c;供参考。 #! /bin/bash ## 打印输出各种*型形…

中企出海,用火山引擎DataTester开启增长第一步

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 今年 Google 宣布其提供的A/B测试工具 Optimize 将在2023年9月30号停止服务。在全球化浪潮席卷下&#xff0c;越来越多的中国企业正在加速走向全球市场&#xff0c;…

使用 Webpack 从 0 到 1 构建 Vue3 项目 + ts

使用 Webpack 从 0 到 1 构建 Vue3 项目 1.初始化项目结构2.安装 webpack&#xff0c;补充智能提示3.初步编写 webpack.config.js3.1设置入口文件及出口文件3.2 指定 html 模板位置 4.配置 运行/打包 命令&#xff0c;首次打包项目5.添加 Vue 及相关配置5.1安装并引入 vue5.2 补…

一个详细且完整的公司局域网搭建案例,跟着操作!

局域网(Local Area Network&#xff0c;简称LAN)&#xff0c;用于将有限范围内&#xff08;例如一个实验室、一层办公楼或者校园&#xff09;的各种计算机、终端与外部设备互联成网。公司局域网怎么建立&#xff1f;首先来了解下不同规模企业网络组建方式。 10人以下企业网络组…

固定资产管理表怎么填写

在现代企业管理中&#xff0c;固定资产的管理是至关重要的环节。它不仅关系到企业运营的效率&#xff0c;也直接影响到企业的财务状况。因此&#xff0c;正确、有效地填写和管理固定资产管理表显得尤为重要。并提供一些创新的方法来优化这一过程。  让我们理解什么是固定资产…

Win10 cmd默认使用管理员身份运行的修改

一、在开始菜单搜索cmd&#xff0c;打开快捷方式文件位置 二、鼠标右键快捷方式&#xff0c;打开属性 三、选择高级&#xff0c;再勾选用管理员身份运行&#xff0c;点击确定即可

文心一言插件开发全流程,ERNIE-Bot-SDK可以调用文心一言的能力

文心一言插件开发 前言插件插件是什么工作原理申请开发权限 开始第一步&#xff1a;安装python第二步&#xff1a;搭建项目manifest 描述文件&#xff1a;ai-plugin.json插件服务描述文件&#xff1a;openapi.yaml开发自己的plugin-server 第三步&#xff1a;上传插件 SDK相关链…

记录一次开机内存分析的全过程

作者&#xff1a;zzy的学习笔记 记录一次开机内存分析的全过程&#xff0c;尽量详尽的介绍常用内存分析工具和命令行的使用&#xff0c;结合具体问题探讨开机内存分析的实践经验。通过这篇文章我会介绍开机内存的常用测试分析工具的基本使用方法&#xff0c;以及如何通过抓取出…

在UMG中播放图像序列,出现卡帧怎么办?

在虚幻引擎中播放图像序列 前期步骤可以参考上面链接中官方文档的步骤1-13 如果在媒体播放器中播放的时候&#xff0c;出现卡帧现象&#xff0c;说明你的图片序列的帧率与默认的不匹配 需要在lmg Media Source类型文件中&#xff0c;覆写你的帧率 比如&#xff0c;我的图片序…

VSCode错误整理

文章目录 一、zsh: command not found: python二、Python pip安装Django异常Could not find a version that satisfies the requirement pytz (from django)三、WARNING: You are using pip version 21.2.4, however version 23.2.1 is available.四、pip install django下载报…

Sui参会必备|Token 2049活动一览

TOKEN2049是在新加坡举办的一年一度首屈一指地加密货币活动&#xff0c;吸引了顶级的Web3公司和项目的创始人和高管&#xff0c;他们将在这里分享行业观点、聚焦全球发展&#xff0c;同时以独特且广泛的视角审视这个生态系统及其广阔的机会。 自5月份主网上线以来&#xff0c;S…

lv3 嵌入式开发-11 Linux下GDB调试工具

目录 1 GDB简介 2 GDB基本命令 3 GDB调试程序 1 GDB简介 GDB是GNU开源组织发布的一个强大的Linux下的程序调试工具。 一般来说&#xff0c;GDB主要帮助你完成下面四个方面的功能&#xff1a; 1、启动你的程序&#xff0c;可以按照你的自定义的要求随心所欲的运行程序&#…

七、MySql表的内置函数

文章目录 一、日期函数&#xff08;一&#xff09;常用日期函数1.获得年月日&#xff1a;2.获得时分秒&#xff1a;3.获得时间戳&#xff1a;4.在日期的基础上加日期&#xff1a;5.在日期的基础上减去时间&#xff1a;6.计算两个日期之间相差多少天 &#xff08;二&#xff09;…

基于Spring Boot 3.1.0的Dubbo代码实现(以Redis作为注册中心)

目录 基于Spring Boot 3.1.0的Dubbo代码实现&#xff08;以Redis作为注册中心&#xff09;一 简介二 前言三 文档查阅四 依赖项1 注意事项2 版本3 dependencyManagement依赖4 dependency依赖 五 配置文件1 注意事项2 代码 六 yml文件 基于Spring Boot 3.1.0的Dubbo代码实现&…

RRU-Net:The Ringed Residual U-Net for Image Splicing Forgery Detection阅读笔记一

文章目录 1. Introduction2. Related Work3. The Ringed Residual U-Net (RRU-Net)3.1. Residual Propagation3.2. Residual Feedback3.3. Ringed Residual Structure and Network Architectures 4. Evaluation Experiment and Comparative Analysis 1. Introduction 根据现有…