【Linux】【驱动】注册字符设备号

【Linux】【驱动】注册字符设备号

  • 1. 绪论
    • 1 、静态分配设备号
    • 2、动态分配设备号
    • 3、注销设备号
  • 2 实现的代码
  • 3 加载驱动程序

1. 绪论

在之前杂项设备的时候,设备号是固定的,字符设备就需要自己去申请设备号了,
申请设备号有两个方式,静态和动态两种

一个字符设备或者块设备都有一个主设备号和次设备号。主设备号和次设备号统称为设备号。主设备
号用来表示一个特定的驱动程序。次设备号用来表示使用该驱动程序的各个设备。Linux 提供了一个名为
dev_t 的数据类型表示设备号,dev_t 定义在文件 include/linux/types.h 里面,
dev_t 是个 32 位的变量,其中 12 位用来表示主设备号,20 位用来表示次设备号。

#define MINORBITS20 //次设备号的位数,一共是 20 位
#define MINORMASK ((1U << MINORBITS) - 1) //次设备号的掩码
#define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS)) //在 dev_t 里面获取我们的主设备号
#define MINOR(dev) ((unsigned int) ((dev) & MINORMASK)) //在 dev_t 里面获取我们的次设备号
#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi)) //将我们的主设备号和次设备号组成一个 dev_t 类型。

1 、静态分配设备号

如下操作可以查看设备号…操作未实现待查看

cat /proc/devices

设备号的静态申请函数

int register_chrdev_region(dev_t *dev, unsigned count,const char *name);

dev 设备号的起始值。类型是 dev_t 类型
count 要申请的次设备号的个数
name 设备名字
返回值 成功返回 0,失败返回负数

2、动态分配设备号

int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)

dev 保存申请到的设备号
baseminor 次设备号起始地址,alloc_chrdev_region 可以申请一段连续的多个设备号,这些设
备号的主设备号一样,但是次设备号不同,次设备号以 baseminor 为起始地址地址
开始递增。一般 baseminor 为 0,也就是说次设备号从 0 开始。

count 要申请的设备号数量
name 设备名字
返回值 成功返回 0,失败返回负数。使用动态分配会优先使用 255 到 234

3、注销设备号

void unregister_chrdev_region(dev_t from, unsigned count)

from 要释放的设备号
count 表示从 from 开始,要释放的设备号数量

2 实现的代码

通过两个方式实现了两个申请设备号的方法,

#include <linux/init.h>
#include <linux/module.h>     //最基本的文件,支持动态添加和卸载模块。
#include <linux/fs.h>        //包含了文件操作相关 struct 的定义,例如大名鼎鼎的 struct file_operations
#include <linux/kdev_t.h>


#define DEVICE_NUMBER 1 		//定义次设备号的个数
#define DEVICE_SNAME "schrdev"  //定义静态注册设备的名称
#define DEVICE_ANAME "achrdev"  //定义动态注册设备的名称
#define DEVICE_MINOR_NUMBER 0 	//定义次设备号的起始地址


static int major_num,minor_num; //定义主设备号和次设备号
module_param(major_num,int,S_IRUSR); //驱动模块传入普通参数 major_num
module_param(minor_num ,int,S_IRUSR);//驱动模块传入普通参数 minor_num




//drivers for init
static int hello_init(void)
{
	dev_t dev_num;
	int ret;//函数返回值
	if(major_num)
	{
		/*静态注册设备号*/
		printk("major_num = %d\n",major_num);//打印传入进来的主设备号
		printk("minor_num = %d\n",minor_num);//打印传入进来的次设备号
		dev_num = MKDEV(major_num,minor_num);//MKDEV 将主设备号和次设备号合并为一个设备号
		ret = register_chrdev_region(dev_num, DEVICE_NUMBER,DEVICE_SNAME);//注册设备号
		if(ret<0)
		{
			printk("register_chrdev_region error\n");
		}
		//静态注册设备号成功,则打印。
		printk("register_chrdev_region ok\n");
	}
	else
	{
		/*动态注册设备号*/
		ret = alloc_chrdev_region(&dev_num,DEVICE_MINOR_NUMBER,1, DEVICE_ANAME);
		if(ret<0)
		{
			printk("alloc_chrdev_region error\n");
		}
		//动态注册设备号成功,则打印
		printk("alloc_chrdev_region ok\n");
		major_num =MAJOR(dev_num); //将主设备号取出来
		minor_num = MINOR(dev_num);//将次设备号取出来
		printk("major_num = %d\n",major_num);//打印传入进来的主设备号
		printk("minor_num = %d\n",minor_num);//打印传入进来的次设备号
	}
	return 0;
}


//drivers for exit 
static void hello_exit(void)
{
	unregister_chrdev_region(MKDEV(major_num,minor_num),DEVICE_NUMBER);//注销设备号
	printk("gooodbye  \n");

}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");

3 加载驱动程序

移动文件

cp chrdev.ko /home/book/nfs_rootfs/

删除文件

rm -f + chrdev.ko

打开printk

echo "7 4 1 7"> /proc/sys/kernel/printk

挂载动态分配的设备号

insmod chrdev.ko

挂载静态分配的设备号

insmod chrdev.ko major_num=9

在这里插入图片描述

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

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

相关文章

Python入门教程 - 基本语法 (一)

目录 一、注释 二、Python的六种数据类型 三、字符串、数字 控制台输出练习 四、变量及基本运算 五、type()语句查看数据的类型 六、字符串的3种不同定义方式 七、数据类型之间的转换 八、标识符命名规则规范 九、算数运算符 十、赋值运算符 十一、字符串扩展 11.1…

如何飞速成为开源贡献者(Contributor)

如何飞速成为开源贡献者Contributor 一、环境信息1.1 硬件信息1.2 软件信息 二、Git安装2.1 Git介绍2.2 Git下载安装 三、开源项目选定四、GitHub参与开源流程4.1 Fork项目4.2 SSH配置4.2.1 为什么要配置SSH4.2.2 如何配置SSH 4.3 Clone项目4.4 IDEA关联4.5 PR生成4.6 PR提交 一…

OceanBase 4.x改装:另一种全链路追踪的尝试

本文作者&#xff1a;夏克 OceanBase 社区文档贡献者&#xff0c;曾多次参与 OceanBase 技术征文比赛&#xff0c;获得优秀名次。从事金融行业核心系统设计开发工作多年&#xff0c;服务于某交易所子公司&#xff0c;现阶段负责国产数据库调研。 本文为 OceanBase 第七期技术征…

java-数组

数组静态初始化写法&#xff1a; //静态初始化数组 int[] age new int[] {7,18,19}; double[] scores new double[]{67.5,77.8,94.2,99};//静态初始化数组简化写法 int[] age1 {7,18,19}; double[] scores2 {67.5,77.8,94.2,99};数组在内存中定义方式&#xff1a; 1.在内…

飞天使-python的面向对象

文章目录 面向对象面向对象思想类的定义和使用继承封装多态访问控制 参考视频 面向对象 面向对象思想 面向过程和面对对象的区别是什么&#xff1f; 答: 复用性高&#xff0c;面向对象类的定义和使用 类型里面的定义的时候 self 不能省去&#xff0c;应该写出 class person:…

开源项目如何推进人工智能

推荐&#xff1a;使用 NSDT场景编辑器快速搭建3D应用场景 对于那些不熟悉这个概念的人来说&#xff0c;开源软件或项目是那些向公众提供源代码的软件或项目&#xff0c;允许他们查看、使用和修改它。使用开源软件和工具具有多种优势&#xff0c;尤其是在构建复杂的基于 AI 的产…

pytorch异常——RuntimeError:Given groups=1, weight of size..., expected of...

文章目录 省流异常报错异常截图异常代码原因解释修正代码执行结果 省流 nn.Conv2d 需要的输入张量格式为 (batch_size, channels, height, width)&#xff0c;但您的示例输入张量 x 是 (batch_size, height, width, channels)。因此&#xff0c;需要对输入张量进行转置。 注意…

09 mysql fetchSize 所影响的服务器和客户端的交互

前言 这是一个 之前使用 spark 的时候 记一次 spark 读取大数据表 OOM OutOfMemoryError: GC overhead limit exceeded 因为一个 OOM 的问题, 当时使用了 fetchSize 的参数 应用服务 hang 住, 导致服务 503 Service Unavailable 在这个问题的地方, 出现了一个查询 32w 的数据…

分布式集群——搭建Hadoop环境以及相关的Hadoop介绍

系列文章目录 分布式集群——jdk配置与zookeeper环境搭建 分布式集群——搭建Hadoop环境以及相关的Hadoop介绍 文章目录 前言 一 hadoop的相关概念 1.1 Hadoop概念 补充&#xff1a;块的存储 1.2 HDFS是什么 1.3 三种节点的功能 I、NameNode节点 II、fsimage与edits…

【代码技巧】深度学习参数管理方案(1)

方法概述 利用argparse工具包进行参数管理 创建BaseOptions类进行基础参数的管理&#xff0c;在建立TrainOptions和TestOpetions继承BaseOptions的基础参数&#xff0c;然后可以再添train或者test阶段的新的参数。 文件结构 创建三个文件如图&#xff0c;分别管理BaseOption…

RocketMQ消息队列-@RocketMQMessageListener实现原理

使用Spring-RocketMQ时&#xff0c;只需要引入rocketmq-spring-boot-starter包&#xff0c;并且定义以下消费者&#xff0c;就可以很简单的实现消息消费 Component RocketMQMessageListener(topic "first-topic", consumerGroup "my-producer-group", s…

6. series对象及DataFrame对象知识总结

【目录】 文章目录 6. series对象及DataFrame对象知识总结1. 导入pandas库2. pd.Series创建Series对象2.1 data 列表2.2 data 字典 3. s1.index获取索引4. s1.value获取值5. pd.DataFrame()-创建DataFrame 对象5.1 data 列表5.2 data 嵌套列表5.3 data 字典 6. df[列索引]…

机器学习——KNN算法

1、&#xff1a;前提知识 KNN算法是机器学习算法中用于分类或者回归的算法&#xff0c;KNN全称为K nearest neighbour&#xff08;又称为K-近邻算法&#xff09; 原理&#xff1a;K-近邻算法采用测量不同特征值之间的距离的方法进行分类。 优点&#xff1a;精度高 缺点&…

基于Stable Diffusion的AIGC服饰穿搭实践

本文主要介绍了基于Stable Diffusion技术的虚拟穿搭试衣的研究探索工作。文章展示了使用LoRA、ControlNet、Inpainting、SAM等工具的方法和处理流程&#xff0c;并陈述了部分目前的实践结果。通过阅读这篇文章&#xff0c;读者可以了解到如何运用Stable Diffusion进行实际操作&…

《Web安全基础》04. 文件上传漏洞

web 1&#xff1a;文件上传漏洞2&#xff1a;WAF 绕过2.1&#xff1a;数据溢出2.2&#xff1a;符号变异2.3&#xff1a;数据截断2.4&#xff1a;重复数据 本系列侧重方法论&#xff0c;各工具只是实现目标的载体。 命令与工具只做简单介绍&#xff0c;其使用另见《安全工具录》…

【MySQL学习笔记】(七)内置函数

内置函数 日期函数示例案例-1案例-2 字符串函数示例 数学函数其他函数 日期函数 示例 获得当前年月日 mysql> select current_date(); ---------------- | current_date() | ---------------- | 2023-09-03 | ---------------- 1 row in set (0.00 sec)获得当前时分秒…

Web安全——穷举爆破上篇(仅供学习)

Web安全 一、概述二、常见的服务1、burpsuite 穷举后台密码2、burpsuite 对 webshell 穷举破解密码3、有 token 防御的网站后台穷举破解密码3.1 burpsuite 设置宏获取 token 对网站后台密码破解3.2 编写脚本获取token 对网站后台密码破解 4、针对有验证码后台的穷举方法4.1 coo…

Autofac中多个类继承同一个接口,如何注入?与抽象工厂模式相结合

多个类继承同一个接口,如何注入&#xff1f;与抽象工厂模式相结合 需求: 原来是抽象工厂模式,多个类继承同一个接口。 现在需要使用Autofac进行选择性注入。 Autofac默认常识: Autofac中多个类继承同一个接口,默认是最后一个接口注入的类。 解决方案&#xff1a;(约定大于配…

ssm+vue“魅力”繁峙宣传网站源码和论文

ssmvue“魅力”繁峙宣传网站源码和论文102 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身…

16 个前端安全知识

16 个前端安全知识 去年 security course 上的是 React&#xff0c;然后学了一些 一些 React 项目中可能存在的安全隐患&#xff0c;今年看了一下列表&#xff0c;正好看到了前端也有更新&#xff0c;所以就把这个补上了。 一个非常好学习各种安全隐患的机构是 https://owasp…