Linux 下注册分析(4)

在这里插入图片描述

系列文章目录


Linux 设备树
Linux 下注册分析(1)
Linux 下注册分析(2)
Linux 下注册分析(3)
Linux 下注册分析(4)


文章目录

  • 系列文章目录
  • 1、device_create
    • 简介
    • device_create
      • device_create_groups_vargs
  • 2、class_register
    • 简介
    • struct class
    • class_register
  • 3、class_create
  • 4、class_interface_register


1、device_create

简介

    device_create 用于创建设备并在 sysfs 中注册指向该设备应该注册到的结构类的指针。这个函数可以被 char 设备类使用。

device_create

device_create
device_create_groups_vargs
// drivers/base/core.c
struct device *device_create(const struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *fmt, ...)
{va_list vargs;struct device *dev;va_start(vargs, fmt);dev = device_create_groups_vargs(class, parent, devt, drvdata, NULL,fmt, vargs);va_end(vargs);return dev;
}
EXPORT_SYMBOL_GPL(device_create);

device_create_groups_vargs

device_create
device_create_groups_vargs
kzalloc(sizeof(*dev), GFP_KERNEL)
device_initialize
device_add
// drivers/base/core.c
static __printf(6, 0) struct device *
device_create_groups_vargs(const struct class *class, struct device *parent,dev_t devt, void *drvdata,const struct attribute_group **groups,const char *fmt, va_list args)
{struct device *dev = NULL;int retval = -ENODEV;if (IS_ERR_OR_NULL(class))goto error;dev = kzalloc(sizeof(*dev), GFP_KERNEL);	// 为设备分配空间if (!dev) {retval = -ENOMEM;goto error;}device_initialize(dev);		// 初始化设备结构体dev->devt = devt;dev->class = class;dev->parent = parent;dev->groups = groups;dev->release = device_create_release;dev_set_drvdata(dev, drvdata);retval = kobject_set_name_vargs(&dev->kobj, fmt, args);if (retval)goto error;retval = device_add(dev);	// 把设备加入到总线上if (retval)goto error;return dev;error:put_device(dev);return ERR_PTR(retval);
}

device_register 函数

// drivers/base/core.c
int device_register(struct device *dev)
{device_initialize(dev);return device_add(dev);
}

    从上可以看出,device_create() 调用了 device_initializedevice_add 两个函数,而这恰恰是 device_register() 做的工作,因此其等效于 device_register()

device_register 函数分析见 Linux 下注册分析(4)# device_register
device_add 函数分析见 Linux 下注册分析(4)# device_add


device_create()、device_register()、deivce_add()区别

2、class_register

简介

    在 Linux 系统中,class_register 是一个非常重要的概念。它是 Linux 内核中用来管理设备驱动程序的一种机制,通过对设备进行分类注册,实现设备间的协作和管理。在 Linux 系统中,设备驱动程序是连接硬件设备和操作系统内核的桥梁,而 class_register 机制可以帮助内核更好地管理这些设备驱动程序,并且提供一种灵活的方式来处理设备的注册和注销。

struct class

// include/linux/device/class.h
struct class {const char		*name;const struct attribute_group	**class_groups;const struct attribute_group	**dev_groups;int (*dev_uevent)(const struct device *dev, struct kobj_uevent_env *env);char *(*devnode)(const struct device *dev, umode_t *mode);void (*class_release)(const struct class *class);void (*dev_release)(struct device *dev);int (*shutdown_pre)(struct device *dev);const struct kobj_ns_type_operations *ns_type;const void *(*namespace)(const struct device *dev);void (*get_ownership)(const struct device *dev, kuid_t *uid, kgid_t *gid);const struct dev_pm_ops *pm;
};

class_register

class_register
kzalloc(sizeof(*cp), GFP_KERNEL)
kset_register(&cp->subsys)
sysfs_create_groups(&cp->subsys.kobj, cls->class_groups)
// drivers/base/class.c
int class_register(const struct class *cls)
{struct subsys_private *cp;struct lock_class_key *key;int error;pr_debug("device class '%s': registering\n", cls->name);if (cls->ns_type && !cls->namespace) {pr_err("%s: class '%s' does not have namespace\n",__func__, cls->name);return -EINVAL;}if (!cls->ns_type && cls->namespace) {pr_err("%s: class '%s' does not have ns_type\n",__func__, cls->name);return -EINVAL;}cp = kzalloc(sizeof(*cp), GFP_KERNEL);if (!cp)return -ENOMEM;klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put);INIT_LIST_HEAD(&cp->interfaces);kset_init(&cp->glue_dirs);key = &cp->lock_key;lockdep_register_key(key);__mutex_init(&cp->mutex, "subsys mutex", key);error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name);if (error)goto err_out;cp->subsys.kobj.kset = class_kset;cp->subsys.kobj.ktype = &class_ktype;cp->class = cls;error = kset_register(&cp->subsys);if (error)goto err_out;error = sysfs_create_groups(&cp->subsys.kobj, cls->class_groups);if (error) {kobject_del(&cp->subsys.kobj);kfree_const(cp->subsys.kobj.name);goto err_out;}return 0;err_out:lockdep_unregister_key(key);kfree(cp);return error;
}

kset_register 详细分析见 Linux 下注册分析(1)# kset_register

sysfs_create_groups 详细分析见 Linux 下注册分析(1)# sysfs_create_groups

3、class_create

class_create
kzalloc(sizeof(*cp), GFP_KERNEL)
class_register(cls)
struct class *class_create(const char *name)
{struct class *cls;int retval;cls = kzalloc(sizeof(*cls), GFP_KERNEL);	// 分配 class 空间if (!cls) {retval = -ENOMEM;goto error;}cls->name = name;cls->class_release = class_create_release;retval = class_register(cls);		// 注册 class,见上面 class_registerif (retval)goto error;return cls;error:kfree(cls);return ERR_PTR(retval);
}

    由上可以看出 class_create 在分配 class 结构体后,然后再调用 class_register 函数。

4、class_interface_register

// drivers/base/class.c
int class_interface_register(struct class_interface *class_intf)
{struct subsys_private *sp;const struct class *parent;struct class_dev_iter iter;struct device *dev;if (!class_intf || !class_intf->class)return -ENODEV;parent = class_intf->class;sp = class_to_subsys(parent);	// 获取 class 的 subsys_private if (!sp)return -EINVAL;/** Reference in sp is now incremented and will be dropped when* the interface is removed in the call to class_interface_unregister()*/mutex_lock(&sp->mutex);// 把 class_interface 链到 sp->interfaces 上list_add_tail(&class_intf->node, &sp->interfaces);if (class_intf->add_dev) {class_dev_iter_init(&iter, parent, NULL, NULL);while ((dev = class_dev_iter_next(&iter)))class_intf->add_dev(dev);class_dev_iter_exit(&iter);}mutex_unlock(&sp->mutex);return 0;
}

【Linux内核|驱动模型】bus/class/device/driver


   
 

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

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

相关文章

第十五届蓝桥杯大赛软件赛省赛Java 大学 B 组(1、2题)

1.报数游戏 问题描述 小蓝和朋友们在玩一个报数游戏。由于今年是 2024 年,他们决定要从小到大轮流报出是 20或 24 倍数的正整数。前 10 个被报出的数是:20,24,40,48,60,72,80,96,100,120。请问第 202420242024个被报出的数是多少? 答案提交 这是一道结果…

批量修改图片资源的属性。

Unity版本2022.3 如图,比如我们想要修改图片的属性的时候,大部分都是 TextureImporter importer (TextureImporter)AssetImporter.GetAtPath("Assets/1.png"); // 获取文件 importer.xxxxxxx xxxxxxx; // 修改属性到这里没什么问题&#xf…

基于神经网络的视频编码NNVC(1):帧内预测

在H.266/VVC发布后,基于传统编码框架提升压缩率越来越难,随着深度学习的发展,研究人员开始尝试将神经网络引入编码器。为此,JVET工作组在2020年成立AHG11小组来专门进行基于神经网络的视频编码的研究。 为了方便研究,工…

C语言初阶牛客网刷题—— HJ97 记负均正【难度:简单】

1. 题目描述 牛客网在线OJ题 1、首先输入要输入的整数个数 n ,然后输入 n 个整数。输出为 n 个整数中负数的个数,和所有正整数的平均值, 结果保留一位小数。 注意: 0 即不是正整数,也不是负数,不计入计算&…

【Web开发】一步一步详细分析使用Bolt.new生成的简单的VUE项目

https://bolt.new/ 这是一个bolt.new生成的Vue小项目,让我们来一步一步了解其架构,学习Vue开发,并美化它。 框架: Vue 3: 用于构建用户界面。 TypeScript: 提供类型安全和更好的开发体验。 Vite: 用于快速构建和开发 主界面如下&#xff1a…

Rabbitmq高级特性之消费方确认

背景: 发送方发送消息之后,到达消费端之后,可能会有以下情况:消息处理成功,消息处理异常。RabbitMQ在向消费者发送消息之后,就会把这条消息给删除掉,那么第二种情况,就会造成消息丢…

基于微信小程序的健身管理系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…

Couchbase UI: Server

在 Couchbase UI 中的 Server(服务器)标签页主要用于管理和监控集群中的各个节点。以下是 Server 标签页的主要内容和功能介绍: 1. 节点列表 显示集群中所有节点的列表,每个节点的详细信息包括: 节点地址&#xff1…

Spark Streaming编程基础

文章目录 1. 流式词频统计1.1 Spark Streaming编程步骤1.2 流式词频统计项目1.2.1 创建项目1.2.2 添加项目依赖1.2.3 修改源目录1.2.4 添加scala-sdk库1.2.5 创建日志属性文件 1.3 创建词频统计对象1.4 利用nc发送数据1.5 启动应用,查看结果 2. 编程模型的基本概念3…

OpenCV imread函数读取图像__实例详解

OpenCV imread函数读取图像__实例详解 本文目录: 零、时光宝盒 一、imread函数定义 二、imread函数支持的文件格式 三、imread函数flags参数详解 (3.1)、Flags-1时,样返回加载的图像(使用alpha通道,否…

ssm基于HTML5的红酒信息分享系统

SSM基于HTML5的红酒信息分享系统是一个专注于红酒领域的综合性信息平台,旨在为红酒爱好者、从业者以及普通消费者提供一个便捷的交流与获取红酒相关信息的空间。 一、系统背景与意义 随着人们生活水平的提高和消费观念的转变,红酒作为一种高雅的饮品&a…

Windows Docker Desktop安装及使用 Docker 运行 MySQL

Docker Desktop是Docker的官方桌面版,专为Mac和Windows用户设计,提供了一个简单易用的界面来管理和运行Docker容器。它集成了Docker引擎,为开发人员提供了一个快速、可靠、可扩展的方式来构建、运行和管理应用。DockerDesktop的优势在于&…

人形机器人,自动驾驶“老炮”创业第二站

造一台人形机器人,或许正在成为2025年最炙手可热的事情。 从去年第四季度开始,伴随着大模型应用的深入,具身智能概念被点燃,其中最鲜明的一个特点是,大量自动驾驶大佬的转行加入。 随便说几个比较有分量的&#xff0…

Flutter_学习记录_基本组件的使用记录

1.TextWidge的常用属性 1.1TextAlign: 文本对齐属性 常用的样式有: TextAlign.center 居中TextAlign.left 左对齐TextAlign.right 有对齐 使用案例: body: Center(child: Text(开启 TextWidget 的旅程吧,珠珠, 开启 TextWidget 的旅程吧&a…

什么是COLLATE排序规则?

在当今数字化世界中,数据的整理、比较和排序是至关重要的。在数据库管理和编程语言中,我们经常需要对字符串进行排序,以展示或处理信息。为了实现这一点,各种系统和工具提供了排序规则,其中COLLATE排序规则就是其中的一…

打印输入单词字符数量统计直方图-C语言第二版

1. 编程要求 多年前写过一篇用 C 语言实现打印单词字符数量统计的直方图的文章, 现在看上去有些混乱, 对一些任务划分不清晰, 全部混在一起. 于是重写了这个编程题, 希望可以给初学者一些参考, 并且我分别用 C, C, Java, Python 四种语言完成了这道编程题, 有兴趣的可以看我另…

认识Django项目模版文件——Django学习日志(二)

1.默认文件介绍 └── djangoproject1/├── djangoproject1/│ ├── urls.py [URL和函数的对应关系]【常用文件】│ ├── settings.py [项目配置文件]【常用文件】│ ├── _init_.py│ ├── wsgi.py [接受网络请求] 【不要动】│ └──…

【JS逆向】前端加密对抗基础

目录 逆向基础断掉调试基本常见的加解密方式 encrypt-labs靶场搭建过程靶场基本教程AES加密key前端体现(固定key)AES服务端获取keyRSA非对称加密DES加密存在规律key明文加签sign加签key在服务端signAESRAS组合 逆向基础 断掉调试 通过浏览器站点控制台(F12),进行断…

C# 多线程同步(Mutex | Semaphore)

Mutex: 用于保护临界区,确保同一时间只有一个线程能够访问共享资源; Semaphore: 允许同时有多个线程访问共享资源,但会限制并发访问的数量。 Mutex运行输出 Semaphore运行输出 namespace SyncThreadDemo {internal class Program{static stri…

复位信号的同步与释放(同步复位、异步复位、异步复位同步释放)

文章目录 背景前言一、复位信号的同步与释放1.1 同步复位1.1.1 综述1.1.2 优缺点 1.2 recovery time和removal time1.3 异步复位1.3.1 综述1.3.2 优缺点 1.4 同步复位 与 异步复位1.5 异步复位、同步释放1.5.1 总述1.5.2 机理1.5.3 复位网络 二、思考与补充2.1 复…