当前位置: 首页 > news >正文

3、Linux驱动开发:模块_传递参数

目录

🍅点击这里查看所有博文

  随着自己工作的进行,接触到的技术栈也越来越多。给我一个很直观的感受就是,某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了,只有经常会用到的东西才有可能真正记下来。存在很多在特殊情况下有一点用处的技巧,用的不多的技巧可能一个星期就忘了。

  想了很久想通过一些手段把这些事情记录下来。也尝试过在书上记笔记,这也只是一时的,书不在手边的时候那些笔记就和没记一样,不是很方便。

  很多时候我们遇到了问题,一般情况下都是选择在搜索引擎检索相关内容,这样来的也更快一点,除非真的找不到才会去选择翻书。后来就想到了写博客,博客作为自己的一个笔记平台倒是挺合适的。随时可以查阅,不用随身携带。

  同时由于写博客是对外的,既然是对外的就不能随便写,任何人都可以看到。经验对于我来说那就只是经验而已,公布出来说不一定我的一些经验可以帮助到其他的人。遇到和我相同问题时可以少走一些弯路。

  既然决定了要写博客,那就只能认真去写。不管写的好不好,尽力就行。千里之行始于足下,一步一个脚印,慢慢来 ,写的多了慢慢也会变好的。权当是记录自己的成长的一个过程,等到以后再往回看时,就会发现自己以前原来这么菜😂。

  本系列博客所述资料均来自互联网资料,并不是本人原创(只有博客是自己写的)。出于热心,本人将自己的所学笔记整理并推出相对应的使用教程,方面其他人学习。为国内的物联网事业发展尽自己的一份绵薄之力,没有为自己谋取私利的想法。若出现侵权现象,请告知本人,本人会立即停止更新,并删除相应的文章和代码。

前言

  在用户态下编程可以通过main来传递命令行参数,而编写一个内核模块则可通过module_param来传递命令行参数。

给模块定义外部参数

  module_param宏是Linux 2.6内核中新增的,该宏被定义在include/linux/moduleparam.h文件中,具体定义如下:

/*** module_param - typesafe helper for a module/cmdline parameter* @value: the variable to alter, and exposed parameter name.* @type: the type of the parameter* @perm: visibility in sysfs.** @value becomes the module parameter, or (prefixed by KBUILD_MODNAME and a* ".") the kernel commandline parameter.  Note that - is changed to _, so* the user can use "foo-bar=1" even for variable "foo_bar".** @perm is 0 if the the variable is not to appear in sysfs, or 0444* for world-readable, 0644 for root-writable, etc.  Note that if it* is writable, you may need to use kparam_block_sysfs_write() around* accesses (esp. charp, which can be kfreed when it changes).** The @type is simply pasted to refer to a param_ops_##type and a* param_check_##type: for convenience many standard types are provided but* you can create your own by defining those variables.** Standard types are:*	byte, short, ushort, int, uint, long, ulong*	charp: a character pointer*	bool: a bool, values 0/1, y/n, Y/N.*	invbool: the above, only sense-reversed (N = true).*/
#define module_param(name, type, perm)				\module_param_named(name, name, type, perm)

  module_param使用了3个参数:变量名,它的类型,以及一个权限掩码用来做一个辅助的sysfs入口。这个宏定义应当放在函数之外,典型的是出现在源文件的前面。

   module_param_named则是另一个变种,以示例说明可使得var变量在内核外的变量名称为var_out。在内核外给var_out赋值等同于给模块内var变量赋值。

static char *whom = "hello \n";
static int var = 1;
module_param(whom,charp,0644);
module_param_named(var_out,var,int,0644);

示例代码

#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("PD");
static char *whom = "hello";
static int var = 1;
module_param(whom,charp,0644);
module_param_named(var_out,var,int,0644);
static int hello_init(void)
{printk("hello_init %s \n",whom);printk("hello_init %d\n",var);return 0;
}
static void hello_exit(void)
{printk("hello_exit %s \n",whom);printk("hello_exit %d\n",var);return;
}
module_init(hello_init);
module_exit(hello_exit);

参数传入

   insmod加载模块时,可直接携带对应的参数。当传入不存在的参数时,会报错unknown parameter

root@ubuntu:# insmod ./hello.ko var=100 var_out=200 whom="test"
root@ubuntu:# rmmod ./hello.ko
root@ubuntu:# dmesg
[ 9730.375507] hello: unknown parameter 'var' ignored
[ 9730.375536] hello_init test
[ 9730.375537] hello_init 200 
[ 9733.244654] hello_exit  test
[ 9733.244655] hello_exit  200

   如不携带参数,则使用模块的默认值。

root@ubuntu:# insmod ./hello.ko
root@ubuntu:# rmmod ./hello.ko
root@ubuntu:# dmesg
[ 9520.771593] hello_init hello 
[ 9520.771594] hello_init 1
[ 9534.227683] hello_exit hello 
[ 9534.227684] hello_exit 1

参数修改

   sysfs: 内核会给一些重要的资源创建专属目录或者文件。每个模块会在/sys/module下创建一个同名的文件夹。

   文件夹在加载时被创建,卸载后立即被销毁。

root@ubuntu:# insmod ./hello.ko var=100 var_out=200 whom="test"
root@ubuntu:# ls /sys/module/hello
coresize  holders  initsize  initstate  notes  parameters  refcnt  sections  srcversion  taint  uevent
root@ubuntu:# rmmod ./hello.ko
root@ubuntu:# ls /sys/module/hello
ls: cannot access '/sys/module/hello': No such file or directory

   在专属目录下的parameters目录中记录了模块参数的外部节点。均是虚拟字符设备,可直接通过控制台echo修改,cat读取。

root@ubuntu:# /sys/module/hello# cat ./parameters/var_out 
200
root@ubuntu:# /sys/module/hello# cat ./parameters/whom 
test
root@ubuntu:# /sys/module/hello# echo 300 > ./parameters/var_out 
root@ubuntu:# /sys/module/hello# echo "hahahaha" > ./parameters/whom 
root@ubuntu:# /sys/module/hello# cat ./parameters/var_out 
300
root@ubuntu:# /sys/module/hello# cat ./parameters/whom 
hahahaha

  上述修改立即生效,在模块退出时查看日志,可知变量值已经被修改。

root@ubuntu:# dmesg
[10522.899811] hello: unknown parameter 'var' ignored
[10522.899837] hello_init test 
[10522.899838] hello_init  200
[10572.883954] hello_exit hahahaha
[10572.883955] hello_exit  300

补充说明

模块信息查询(modinfo)

  源文件中记录的额外信息,都会在编译后被打包到ko文件中,以下示例中仅列出一部分。

MODULE_LICENSE("GPL");
MODULE_AUTHOR("PD");
MODULE_DESCRIPTION("3_param example");
MODULE_ALIAS("example3");
MODULE_PARM_DESC(var,"Boolean to enable debugging (0/1 == off/on)");

  在shell中可通过modinfo查询模块的全部信息。

root@ubuntu:# modinfo ./hello.ko
filename:       ./hello.ko
alias:          example3
description:    3_param example
author:         PD
license:        GPL
srcversion:     6D5DF27C63EBFF621C183E3
depends:        
retpoline:      Y
name:           hello
vermagic:       4.15.0-142-generic SMP mod_unload 
parm:           whom:charp
parm:           var_out:int
parm:           var:Boolean to enable debugging (0/1 == off/on)

mask权限问题

  parameters中的对外参数所持有的权限,与代码中module_param注册时填写的权限一致。


module_param(whom,charp,0644);
module_param_named(var_out,var,int,0644);root@ubuntu:# ll /sys/module/hello/parameters/
total 0
drwxr-xr-x 2 root root    0 Jul 22 03:59 ./
drwxr-xr-x 6 root root    0 Jul 22 03:58 ../
-rw-r--r-- 1 root root 4096 Jul 22 03:59 var_out
-rw-r--r-- 1 root root 4096 Jul 22 03:59 whom

  该权限不能超过module_param_call的mask最大权限,若填写的权限比mask大,则最终效果是以mask为准。对外的现象就是设置的权限不起作用。

/* This is the fundamental function for registering boot/moduleparameters. */
#define __module_param_call(prefix, name, ops, arg, perm, level)	\/* Default value instead of permissions? */			\static int __param_perm_check_##name __attribute__((unused)) =	\BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2))	\+ BUILD_BUG_ON_ZERO(sizeof(""prefix) > MAX_PARAM_PREFIX_LEN);	\static const char __param_str_##name[] = prefix #name;		\static struct kernel_param __moduleparam_const __param_##name	\__used								\__attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \= { __param_str_##name, ops, perm, level, { arg } }

  本例中参数声明时指定权限为0666,结果实际加载后参数文件的权限还是0644。

module_param(whom,charp,0666);
module_param_named(var_out,var,int,0666);
root@ubuntu:# ll /sys/module/hello/parameters/
total 0
drwxr-xr-x 2 root root    0 Jul 22 03:59 ./
drwxr-xr-x 6 root root    0 Jul 22 03:58 ../
-rw-r--r-- 1 root root 4096 Jul 22 03:59 var_out
-rw-r--r-- 1 root root 4096 Jul 22 03:59 whom

  那么本篇博客就到此结束了,这里只是记录了一些我个人的学习笔记,其中存在大量我自己的理解。文中所述不一定是完全正确的,可能有的地方我自己也理解错了。如果有些错的地方,欢迎大家批评指正。如有问题直接在对应的博客评论区指出即可,不需要私聊我。我们交流的内容留下来也有助于其他人查看,说不一定也有其他人遇到了同样的问题呢😂。

相关文章:

3、Linux驱动开发:模块_传递参数

目录 &#x1f345;点击这里查看所有博文 随着自己工作的进行&#xff0c;接触到的技术栈也越来越多。给我一个很直观的感受就是&#xff0c;某一项技术/经验在刚开始接触的时候都记得很清楚。往往过了几个月都会忘记的差不多了&#xff0c;只有经常会用到的东西才有可能真正记…...

基于 ThinkPHP 5.1(稳定版本) 开发wms 进销存系统源码

基于ThinkPHP 5.1&#xff08;LTS版本&#xff09;开发的WMS进销存系统源码 管理员账号密码&#xff1a;admin 一、项目简介 这个系统是一个基于ThinkPHP框架的WMS进销存系统。 二、实现功能 控制台 – 权限管理&#xff08;用户管理、角色管理、节点管理&#xff09; – 订…...

全面解析 SOCKS5 代理和 HTTP 代理在网络安全与爬虫应用中的技术对比与应用指南

一、SOCKS5 代理和 HTTP 代理的基本原理 SOCKS5 代理&#xff1a;SOCKS5 是一种网络协议&#xff0c;可以在传输层代理 TCP 和 UDP 请求。它不解析请求内容&#xff0c;仅在客户端和代理服务器之间建立连接&#xff0c;并转发数据。SOCKS5 代理支持众多网络协议和端口类型&…...

DevOps系列文章 之 docker 制作kafka镜像

Docker制作Kafka镜像教程 概述 本教程将指导你如何使用Docker制作一个Kafka镜像。Kafka是一个高性能、分布式的消息队列系统&#xff0c;用于处理大规模的实时数据流。使用Docker制作Kafka镜像可以方便地部署和管理Kafka集群。 整体流程 下面是制作Kafka镜像的整体流程&#xf…...

iPhone 安装 iOS 17公测版(Public Beta)

文章目录 步骤1. 备份iPhone资料步骤2. 申请iOS 17 公测Beta 资格步骤3. 下载iOS 16 Beta 公测描述档步骤4. 选择iOS 17 Beta 公测描述档更新项目步骤5. 升级iOS 17 Public Beta 公开测试版 苹果已经开始向大众释出首个iOS 17 公开测试版/ 公测版( iOS 17 Public Beta)&#xf…...

Spingboot yaml 配置文件及数据读取

属性配置在这里插入图片描述 修改服务器端口 → server.port80 修改 banner → spring.main.banner off(关闭)/console(控制台)/log(日志) 日志 → logging.level.rootinfo Common Application Properties 配置文件分类 优先级 如果三种文件共存时&#xff0c;优先级为&am…...

vue中使用axios发送请求时,后端同一个session获取不到值

问题描述&#xff1a; 在登录页面加载完成后通过axios请求后端验证码接口&#xff08;这时后端会生成一个session用于保存验证码数值&#xff09;&#xff0c;当输入完用户名、密码、验证码后请求登录接口&#xff0c;报错验证码输入错误&#xff0c;打印后端保存验证码的sessi…...

html请求谷歌音频跨域问题(谷歌翻译接口)虚拟机ping不通google(下载谷歌音频、下载百度翻译音频)

文章目录 调用谷歌翻译接口&#xff0c;尝试了几种方案&#xff0c;都提示跨域不行第一种&#xff08;通过js代码获取音频文件的Blob对象&#xff0c;提示跨域了&#xff09;代码结果 第二种&#xff08;尝试新窗打开音频url&#xff0c;404&#xff0c;估计也是跨域了&#xf…...

【设计模式|结构型】享元模式(Flyweight Pattern)

概述 享元模式&#xff08;Flyweight Pattern&#xff09;是一种结构型设计模式&#xff0c;它旨在通过共享对象来减少系统中的对象数量&#xff0c;以便在有限的内存中节省空间和提高性能。在享元模式中&#xff0c;对象分为两部分&#xff1a;内部状态&#xff08;Intrinsic…...

最小覆盖子串(JS)

最小覆盖子串 给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串&#xff0c;则返回空字符串 “” 。 注意&#xff1a; 对于 t 中重复字符&#xff0c;我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量…...

<C语言> 预处理和宏

1.预定义符号 __FILE__ //进行编译的源文件 __LINE__ //文件当前的行号 __DATE__ //文件被编译的日期 __TIME__ //文件被编译的时间 __STDC__ //如果编译器遵循ANSI C&#xff0c;其值为1&#xff0c;否则未定义这些预定义符号都是C语言内置的。 举个例子&…...

代驾公司如何进行运营分析

在这个快节奏的社会中&#xff0c;人们的生活节奏也在不断加快&#xff0c;对于代驾服务的需求也日益增长。然而&#xff0c;如何在这个竞争激烈的市场中&#xff0c;让订单稳稳地握在自己的手中&#xff0c;成为了每一个代驾公司都需要深思的问题。那么&#xff0c;代驾公司如…...

初学HTML:采用CSS绘制一幅夏天的图

下面代码使用了HTML和CSS来绘制一幅炎炎夏日吃西瓜的画面。其中&#xff0c;使用了伪元素和阴影等技巧来实现部分效果。 <!DOCTYPE html> <html> <head><title>炎炎夏日吃西瓜</title><style>body {background-color: #add8e6; /* 背景颜…...

经典文献阅读之--NoPe-NeRF(优化无位姿先验的神经辐射场)

0. 简介 在没有预先计算相机姿态的情况下训练神经辐射场&#xff08;NeRF&#xff09;是具有挑战性的。最近在这个方向上的进展表明&#xff0c;在前向场景中可以联合优化NeRF和相机姿态。然而&#xff0c;这些方法在剧烈相机运动时仍然面临困难。我们通过引入无畸变单目深度先…...

在docker中没有vi如何修改docker中的文件

今天在做学成在线的项目&#xff0c;遇到了一个问题&#xff0c;就是死活登不上xxl-job&#xff0c;按照之前遇到的nacos的问题&#xff0c;我怀疑很大概率是和当时的ip设置有关&#xff0c;不知道nacos的ip怎么修改的同学&#xff0c;可以看看这篇文章&#xff1a;关于docker中…...

【Docker】Docker应用部署之Docekr容器安装Nginx

目录 一、搜索镜像 二、拉取镜像 三、创建容器 四、测试使用 一、搜索镜像 docker search nginx 二、拉取镜像 docker pull nginx # 不加冒号版本号 默认拉取最新版 三、创建容器 首先我们需要在宿主机创建数据卷目录 mkdir nginx # 创建目录 cd nginx # 进入目录 mkd…...

flutter开发实战-jsontodart及 生成Dart Model类

flutter开发实战-jsontodart及 生成Dart Model类。 在开发中&#xff0c;经常遇到请求的数据Json需要转换成model类。这里记录一下Jsontodart生成Dart Model类的方案。 一、JSON生成Dart Model类 在开发中经常用到将json转成map或者list。通过json.decode() 可以方便 JSON 字…...

C++复刻:[流光按钮]+[悬浮波纹按钮]

目录 参考效果实现main.cppdialog.hdialog.cppflowingRayButton.h 流动光线按钮flowingRayButton.cpp 流动光线按钮hoveringRippleButton.h 悬浮波纹按钮hoveringRippleButton.cpp 悬浮波纹按钮模糊知识点 源码 参考 Python版本&#xff1a;GitHub地址 B站主页 效果 实现 ma…...

CompletableFuture 详解

目录 简单介绍 常见操作 创建 CompletableFuture new 关键字 静态工厂方法 处理异步结算的结果 简单介绍 CompletableFuture 同时实现了 Future 和 CompletionStage 接口。 public class CompletableFuture<T> implements Future<T>, CompletionStage<T…...

el-table数据处理

在写表格时遇到&#xff0c;后端返回的数据是对象&#xff0c;并且缺少字段 1.每一条数据加上 一个字段 2.将对象转成数组 以下是数据 {"groupA": {"groupName": null,"orgName": null,"orgId": null,"allPeoper": &quo…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

NFT模式:数字资产确权与链游经济系统构建

NFT模式&#xff1a;数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新&#xff1a;构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议&#xff1a;基于LayerZero协议实现以太坊、Solana等公链资产互通&#xff0c;通过零知…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?

Pod IP 的本质与特性 Pod IP 的定位 纯端点地址&#xff1a;Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址&#xff08;如 10.244.1.2&#xff09;无特殊名称&#xff1a;在 Kubernetes 中&#xff0c;它通常被称为 “Pod IP” 或 “容器 IP”生命周期&#xff1a;与 Pod …...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...