lv13 内核模块参数和依赖

1 模块传参

1.1 模块参数设置

将指定的全局变量设置成模块参数

module_param(name,type,perm);//将指定的全局变量设置成模块参数
/*
name:全局变量名
type:使用符号      实际类型                传参方式bool         bool           insmod xxx.ko  变量名=0 或 1invbool      bool           insmod xxx.ko  变量名=0 或 1charp        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  
*/

注:perm变量名操作权限一般都设置为0664,对应110(用户可读写),110(组可读写 100,(其他用户可读) 。若是数组变量,存放数组大小变量的地址,可以填NULL(确保传参个数不越界)。

1.2 示例:

testparam.c

#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 testparam_init(void)
{int i = 0;printk("gx=%d\n",gx);printk("gstr=%s\n",gstr);for(i = 0;i < 5;i++){printk("%d ",garr[i]);}printk("\n");return 0;
}void __exit testparam_exit(void)
{printk("testparam will exit\n");
}MODULE_LICENSE("GPL");
//MODULE_AUTHOR("4IOT");
//MODULE_DESCRIPTION("It is only a simple test");
//MODULE_ALIAS("HI");module_init(testparam_init);
module_exit(testparam_exit);

修改MakeFile

ifeq ($(KERNELRELEASE),)ifeq ($(ARCH),arm)
KERNELDIR ?= /home/linux/Linux_4412/kernel/linux-3.14
ROOTFS ?= /opt/4412/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesmodules_install:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules INSTALL_MOD_PATH=$(ROOTFS) modules_installclean:rm -rf  *.o  *.ko  .*.cmd  *.mod.*  modules.order  Module.symvers   .tmp_versionselse
CONFIG_MODULE_SIG=n
obj-m += testparam.oendif

编译运行

带参数编译运行

用法:用参数控制内核某个功能是否执行 

1.3 参数描述

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

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

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

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

2 模块依赖

2.1 模块依赖规则

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

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

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

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

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

第一列:其相对地址(即相对位置)

D代表全局变量(初始化过的)

T代表函数

B代表全局变量 (未被初始化)

R代表加了const的全局变量

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

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编译后

 查看

vi /proc/kallsyms  //运行起来就没有相对地址了,给绝对地址也不安全所以都是0
vi /boot/System.map

 

 

 

开发板查看符号表

vim vmlinux

 

2.2 示例(2个模块同目录下):

moduleA.c

#include <linux/module.h>
#include <linux/kernel.h>int gx = 19;EXPORT_SYMBOL(gx);int __init moduleA_init(void)
{printk("In module_a init gx=%d\n",gx);return 0;
}void __exit moduleA_exit(void)
{printk("moduleA will exit\n");
}//MODULE_AUTHOR("4IOT");
//MODULE_DESCRIPTION("It is only a simple test");
//MODULE_ALIAS("HI");module_init(moduleA_init);
module_exit(moduleA_exit);

moduleB.c

#include <linux/kernel.h>extern int gx;int __init moduleB_init(void)
{printk("\n");return 0;
}void __exit moduleB_exit(void)
{printk("moduleB will exit\n");
}MODULE_LICENSE("GPL");
//MODULE_AUTHOR("4IOT");
//MODULE_DESCRIPTION("It is only a simple test");
//MODULE_ALIAS("HI");module_init(moduleB_init);
module_exit(moduleB_exit);

MakeFile(注意编译顺序)

ifeq ($(KERNELRELEASE),)ifeq ($(ARCH),arm)
KERNELDIR ?= /home/linux/Linux_4412/kernel/linux-3.14
ROOTFS ?= /opt/4412/rootfs
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
endif
PWD := $(shell pwd)modules:$(MAKE) -C $(KERNELDIR) M=$(PWD) modulesmodules_install:$(MAKE) -C $(KERNELDIR) M=$(PWD) modules INSTALL_MOD_PATH=$(ROOTFS) modules_installclean:rm -rf  *.o  *.ko  .*.cmd  *.mod.*  modules.order  Module.symvers   .tmp_versionselse
CONFIG_MODULE_SIG=n
obj-m += moduleA.o   //需要先编译moduleA
obj-m += moduleB.oendif

编译

插入模块(注意插入顺序)

移除模块(注意移除顺序)

2.3 示例(2个模块不同目录)

新建两个目录moda、modb

分别把之前示例的.c和Makefile放到moda和modb目录下 

修改Makefile只编译目录下的可执行文件。

编译的时候必须先编译A,否则会报错,如下图。编译完A后需要把生成的.symvers文件拷贝到B再再编译B。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kafka集群详解

Kafka介绍Kafka集群介绍Kafka集群特点Kafka集群搭建在这里插入图片描述Kafka集群如何进行故障切换Kafka集群Leader的选举Kafka集群如何快速横向拓展Kafka集群搭建最佳实践Kafka集群可以使用单节点Zookeeper吗Kafka集群的消费者信息保存在那里Kafka集群的Topic的分区数的设置规则…

区块链的三难困境是什么,如何解决?

人们需要保持社交、工作和睡眠之间的平衡&#xff0c;并且努力和谐相处。同样的概念也反映在区块链的三难困境中。 区块链三难困境是一个术语&#xff0c;指的是现有区块链的局限性&#xff1a;可扩展性、安全性和去中心化。这是一个存在了几十年的设计问题&#xff0c;其问题的…

使用SecoClient软件连接L2TP

secoclient软件是华为防火墙与友商设备进行微屁恩对接的一款软件,运行在windows下可以替代掉win系统自带的连接功能,因为win系统自带的连接功能总是不可用而且我照着网上查到的各种方法调试了很久都调不好,导致我一度怀疑是我的服务没搭建好,浪费了大把时间去研究其他搭建方案 …

鸿蒙 Window 环境的搭建

鸿蒙操作系统是国内自研的新一代的智能终端操作系统&#xff0c;支持多种终端设备部署&#xff0c;能够适配不同类别的硬件资源和功能需求。是一款面向万物互联的全场景分布式操作系统。 下载、安装与配置 DevEco Studio支持Windows系统和macOS系统 Windows系统配置华为官方推…

web网站的工作流程和开发模式

web网站的工作流程和开发模式 基于Java Script封装的高级技术&#xff1a;Vue、Element、Nginx(前端程序部署的服务器) 初识Web前端 Web标准

Cisco模拟器-企业网络部署

某企业园区网有&#xff1a;2个分厂&#xff08;分别是&#xff1a;零件分厂、总装分厂&#xff09;1个总厂网络中心 1个总厂会议室&#xff1b; &#xff08;1&#xff09;每个分厂有自己的路由器&#xff0c;均各有&#xff1a;1个楼宇分厂网络中心 每个楼宇均包含&#x…

数据库 范式

概念 一个低一级范式的关系模式通过模式分解可以转换成若干个高一级范式的关系集合&#xff0c;这种过程就叫规范化。 关系数据库中的关系是要满足一定要求的&#xff0c;满足不同程度要求的位不同范式。 部分依赖&完全依赖 定义&#xff1a;在关系 R(U) 中&#xff0c…

【CFP-专栏2】计算机类SCI优质期刊汇总(含IEEE/Top)

一、计算机区块链类SCI-IEEE 【期刊概况】IF:4.0-5.0, JCR2区&#xff0c;中科院2区&#xff1b; 【大类学科】计算机科学&#xff1b; 【检索情况】SCI在检&#xff1b; 【录用周期】3-5个月左右录用&#xff1b; 【截稿时间】12.31截稿&#xff1b; 【接收领域】区块链…

第3课 使用FFmpeg获取并播放音频流

本课对应源文件下载链接&#xff1a; https://download.csdn.net/download/XiBuQiuChong/88680079 FFmpeg作为一套庞大的音视频处理开源工具&#xff0c;其源码有太多值得研究的地方。但对于大多数初学者而言&#xff0c;如何快速利用相关的API写出自己想要的东西才是迫切需要…

GO学习记录 —— 创建一个GO项目

文章目录 前言一、项目介绍二、目录介绍三、创建过程1.引入Gin框架、创建main2.加载配置文件3.连接MySQL、redis4.创建结构体5.错误处理、返回响应处理 前言 代码地址 下载地址&#xff1a;https://github.com/Lee-ZiMu/Golang-Init.git 一、项目介绍 1、使用Gin框架来创建项…

C#基础环境搭建

一.Microsoft .NET Framework 确保系统中安装Microsoft .NET Framework相关版本下载 .NET Framework 4.7 | 免费官方下载 (microsoft.com)https://dotnet.microsoft.com/zh-cn/download/dotnet-framework/net47 二.编译环境搭建 已经集成编译工具csc.exe DirectX外部依赖,归档…

计算机操作系统(OS)——P4文件管理

1、初始文件管理 1.1、文件的属性 1&#xff09;文件名&#xff1a;由创建文件的用户决定文件名&#xff0c;主要是为了方便用户找到文件&#xff0c;同一目录下不允许有重名文件。 2&#xff09;标识符&#xff1a;一个系统内的各文件标识符唯一&#xff0c;对用户来说毫无…