sysfs文件系统

news2025/1/11 14:46:27

sysfs系统介绍

  • sysfs系统
    • sysfs系统是什么?
      • koject的内核对象模型基础
      • kobject结构体定义
      • kest
    • bus如何管理driver和device
      • bus_type 结构体
    • 小知识
      • 什么是挂载
      • mount命令

📌————本章重点————📌
🔗了解sysfs系统概念;
🔗了解kobject,kest结构体;
🔗了解bus如何管理driver和device;
✨————————————✨

在这里插入图片描述

sysfs系统

sysfs系统是什么?

sysfs是一种虚拟文件系统,旨在提供一种访问内核数据结构的方法,从而允许用户空间程序查看和控制系统的设备和资源。sysfs文件系统通常被挂载在/sys目录下。sysfs提供了一种以树状结构组织的系统信息的方式,其中每个设备都有一个唯一的目录来表示它自己,其中包含有关设备的各种属性和状态信息的文件。这些文件通常是只读的,但有些也可以用于修改设备的某些设置。sysfs还提供了一个机制来通知用户空间程序有关设备状态更改的信息,从而使其能够对这些更改做出反应。sysfs文件系统被广泛用于Linux内核中,它为开发者提供了一种简单的方式来管理和控制系统中的各种设备和资源。

我们知道,在linux系统下一切皆文件,所以设备也是linux下的一个文件。

由mount命令我们可以看到,sysfs挂在在sys目录下
在这里插入图片描述
我们可以进入下面这个文件夹查看设备驱动程序信息
总线都会放到/sys/bus这个目录下,其中设备驱动程序信息在/sys/bus/platform/drivers下
在这里插入图片描述

具体理解我们可以参考以下图表:

在这里插入图片描述
1.Bus(总线)
总线是一种用于连接多个硬件设备的物理或逻辑通道,它是计算机系统中最重要的组成部分之一,负责将各种设备连接到主板上,并通过数据传输来实现这些设备之间的通信。在 Linux 操作系统中,总线是一种抽象的概念,用于描述硬件设备之间的连接方式和通讯协议。常见的总线类型包括 PCI、USB、SATA、I2C 等。Linux 内核通过识别总线来自动发现和配置连接在总线上的硬件设备。

2.Devices(设备)
设备是指连接在总线上的硬件设备,例如磁盘驱动器、网卡、USB 设备等。在 Linux 操作系统中,每个设备都会被分配一个唯一的设备文件(device file),用于表示设备在文件系统中的位置。设备文件通常位于 /dev 目录下,例如硬盘设备文件为 /dev/sda、USB 设备文件为 /dev/usb。

3.Classes(设备类)
设备类是一种用于分类和管理设备的机制。在 Linux 操作系统中,每个设备都会被分配一个设备类,例如磁盘设备属于 block 类、网络设备属于 net 类。设备类用于将相似的设备归类到一起,并提供一组共同的属性和接口。例如,所有 block 类设备都具有读写数据的接口,所有 net 类设备都具有配置网络参数的接口,比如Block 类设备是一种按照固定大小的块(通常为512字节或4KB)来访问的存储设备,例如硬盘、闪存、光盘等。Block 类设备提供了读取和写入块数据的接口,同时也支持块设备缓存、磁盘分区、文件系统等功能。

4.总线、设备和设备类之间的链接方式如下:

每个设备都属于一个设备类,设备类定义了设备的属性和接口。
每个设备都连接到一个总线上,总线通过 ID 来唯一标识每个设备。
每个设备节点都与一个设备相关联,设备节点的名称由设备类决定。

koject的内核对象模型基础

在 Linux 内核中,kobject 是内核对象(Kernel Object)的一种抽象表示。它是内核对象模型的基础,用于表示内核中的各种资源(如设备、驱动程序、进程等),并提供统一的管理和操作接口。是设备模型的核心,引入了通用对象属性的封装概念。kobject 通常用于表示驱动程序中的设备对象,即 struct device 结构体的成员。当设备驱动程序被加载到内核中时,驱动程序会注册一个 struct device_driver 结构体,其中包含了设备对象的信息。内核将创建一个 kobject 对象来表示该设备对象,并将其添加到设备模型中。然后,用户空间可以使用 sysfs 接口来查询和配置设备对象的属性,例如设备状态、驱动程序信息等。头文件:<linux/kobject.h>
在这里插入图片描述
如上图相当于是一种层层封装的结构

kobject结构体定义

struct kobject {
    const char              *name;
    struct list_head        entry;
    struct kobject          *parent;
    struct kset             *kset;
    struct kobj_type        *ktype;
    struct sysfs_dirent     *sd;
    struct kref             kref;
    unsigned int            state_initialized:1;
    unsigned int            state_in_sysfs:1;
    unsigned int            state_add_uevent_sent:1;
    unsigned int            state_remove_uevent_sent:1;
    unsigned int            uevent_suppress:1;
};

各个属性解释:

name:kobject 对象的名称,用于标识该对象在对象树中的位置。
entry:kobject 对象在父对象的子对象链表中的节点。
parent:kobject 对象的父对象,即该对象在对象树中的父节点。
kset:kobject 对象所属的 kset 对象,用于管理该对象的生命周期。
ktype:kobject 对象所属的 kobj_type 对象,用于定义该对象的属性和操作。
sd:sysfs 中与该 kobject 对象对应的 sysfs_dirent 对象。
kref:用于实现 kobject 对象的引用计数,确保该对象在被使用时不被释放。
state_initialized:标识该 kobject 对象是否已经初始化。
state_in_sysfs:标识该 kobject 对象是否已经在 sysfs 中注册。
state_add_uevent_sent:标识该 kobject 对象是否已经发送了添加事件通知。
state_remove_uevent_sent:标识该 kobject 对象是否已经发送了删除事件通知。
uevent_suppress:标识是否禁止该 kobject 对象发送事件通知。

每个内核设备直接或间接嵌入kobject属性。在添加到系统之前,必须使用kobject_ create()函数分配kobject,并将已经分配但尚未初始化的kob ject指针及其kobject_type 指针作为参数。kobject_add()函数用于添加kobject并将其链接到系统,同时根据其层次结构创建目录及其默认属性。功能与之相反的函数是kobject_ del(),将kobject删除链接

kest

kset 是一种特殊的 kobject,它代表一组相关的内核对象,可以通过 sysfs 接口暴露给用户空间。kset 可以看作是 kobject 的容器,它可以包含多个 kobject,并提供了一些方便的接口来管理这些 kobject。设备驱动程序可以创建一个 kset 来表示该驱动程序的设备对象集合,并将每个设备对象表示为一个 kobject,然后将它们添加到 kset 中。头文件:<linux/kobject.h>

struct kset {
    struct kobject kobj;  // kset 对应的 kobject
    struct list_head list;  // kset 链表
    struct kset_uevent_ops *uevent_ops;  // uevent 操作函数指针
    const char *subsys;  // kset 所属子系统的名称
    struct kobject *kobj_child;  // 子对象的 kobject 指针
    struct kobject *kobj_unregister;  // 未注册的 kobject 指针
    struct module *module;  // kset 所属的内核模块
};

kobj:一个 kobject 对象,表示 kset 对象本身。
list:一个链表,用于将多个 kset 对象连接在一起。
uevent_ops:一个指向 kset_uevent_ops 结构体的指针,表示 kset 对象的 uevent 操作函数集。
subsys:一个字符串,表示 kset 对象所属的子系统名称。
kobj_child:一个指向 kobject 对象的指针,表示 kset 包含的子对象的 kobject。
kobj_unregister:一个指向 kobject 对象的指针,表示未注册的 kobject,用于在 kset 删除时释放该对象。
module:一个指向 struct module 结构体的指针,表示 kset 所属的内核模块。

在这里插入图片描述
在这个目录下的每一个子目录,其实都是相同类型的koject集合,不同的kest组织成树状层次结构,就构成了sysfs子目录

bus如何管理driver和device

在 Linux 内核中,bus 是一种抽象的总线结构,用于管理和控制设备和设备驱动程序之间的交互。每个 bus 对象都有一个相应的 bus_type 结构体,它包含了管理 bus 对象所需的函数和数据。bus 对象还可以包含多个 device 对象和多个 driver 对象。

driver 是一种抽象的设备驱动程序结构,用于实现设备的控制和数据交换。每个 driver 对象都有一个相应的 driver_type 结构体,它包含了实现 driver 所需的函数和数据。driver 对象还可以匹配多个 device 对象,并与之交互。

device 是一种抽象的设备结构,用于表示系统中的物理设备或虚拟设备。每个 device 对象都有一个相应的 device_type 结构体,它包含了描述 device 特性和行为的数据。device 对象还可以与多个 driver 对象匹配,并通过它们来控制和管理设备。

当内核探测到一个新的设备时,它会将设备信息和一些系统信息传递给 bus 对象。bus 对象会根据设备信息匹配合适的 driver 对象,并在匹配成功时将 device 对象与 driver 对象绑定。这样,driver 对象就可以访问 device 对象的属性和方法,并与设备交互。

在设备使用过程中,内核会通过 bus 对象和 driver 对象来控制和管理设备。例如,当设备需要进行初始化、启动、停止、重启或卸载时,内核会调用相应的 driver 函数来完成这些操作。同样,当设备出现故障或需要进行调试时,内核也会通过 bus 对象和 driver 对象来诊断和处理问题。

总之,bus、driver 和 device 是 Linux 内核中用于管理和控制设备和设备驱动程序的重要抽象结构。通过这些结构,内核可以实现设备的自动探测、自动匹配、自动配置和自动管理,从而使设备的使用更加方便和可靠。

在这里插入图片描述
在 Linux 内核中,kobject 和 subsys_private 通常是一一对应的。kobject 结构体表示内核中的对象,而 subsys_private 结构体表示该对象所属的子系统的私有数据。在子系统中,可以通过 kobject 结构体的 kset 成员指针访问该对象所属的 kset 结构体,进而获取子系统的 subsys_private 结构体。一般来说,subsys_private 结构体中包含了与子系统相关的所有数据,如对象列表、状态信息、配置参数等。
例如,在 Linux 设备驱动程序中,一个设备对象的 kobject 结构体中的 kset 成员指针通常指向该设备所属的 bus_type 结构体中的 devices_kset 成员,而 devices_kset 成员又指向设备子系统的 subsys_private 结构体。通过访问 subsys_private 结构体,设备驱动程序可以获取设备子系统的私有数据和状态信息,进而实现设备的初始化、配置和管理。总之,kobject 结构体和 subsys_private 结构体是 Linux 内核中一对重要的结构体,它们通常是一一对应的,表示内核中的对象和该对象所属的子系统的私有数据。通过访问 subsys_private 结构体,内核组件可以获取和修改子系统的私有数据和状态信息,实现对象之间的协同工作。

bus_type 结构体

bus_type 结构体是 Linux 内核中用于表示总线类型的结构体,通常定义在头文件 include/linux/device.h 中。该结构体中包含了一些总线类型的属性和操作方法。

struct bus_type {
    const char *name;                       // 总线类型的名称
    const char *dev_name;                   // 设备文件名的前缀
    struct bus_attribute *bus_attrs;        // 总线类型的属性
    struct device_attribute *dev_attrs;     // 设备属性
    struct driver_attribute *drv_attrs;     // 驱动程序属性
    int (*match)(struct device *dev, struct device_driver *drv);   // 匹配函数
    int (*uevent)(struct device *dev, struct kobj_uevent_env *env); // 热插拔事件函数
    int (*probe)(struct device *dev);       // 探测函数
    int (*remove)(struct device *dev);      // 卸载函数
    void (*shutdown)(struct device *dev);   // 关机函数
    struct device * (*add_device)(struct device *dev); // 添加设备
    void (*remove_device)(struct device *dev); // 移除设备
    struct device_driver * (*match_driver)(struct device *dev, struct bus_type *bus); // 匹配驱动程序
    const struct dev_pm_ops *pm;            // 电源管理操作函数
    struct lock_class_key lock_key;         // 锁的标识符
    struct module *owner;                   // 模块的所有者
};

name:表示总线类型的名称,通常是一个字符串,如 “pci”、“usb” 等。
dev_name:表示设备文件名的前缀,当设备注册到该总线类型时,内核会为该设备创建一个设备文件,其文件名的前缀为
dev_name,后面会跟上一个数字,如 /dev/ttyUSB0。 bus_attrs:指向一个 bus_attribute
结构体数组,表示总线类型的属性。bus_attribute 结构体用于定义总线类型的属性,通常是一个 sysfs
文件,用于管理总线类型的参数和状态信息。 dev_attrs:指向一个 device_attribute
结构体数组,表示该总线类型下设备的属性。device_attribute 结构体用于定义设备的属性,通常是一个 sysfs
文件,用于管理设备的参数和状态信息。 drv_attrs:指向一个 driver_attribute
结构体数组,表示该总线类型下驱动程序的属性。driver_attribute 结构体用于定义驱动程序的属性,通常是一个 sysfs
文件,用于管理驱动程序的参数和状态信息。
match:用于匹配设备和驱动程序的函数指针,当一个新的设备加入到该总线类型中时,内核会调用该函数来匹配该设备所需的驱动程序。
uevent:用于处理热插拔事件

小知识

什么是挂载

==挂载(Mount)是将文件系统链接到操作系统的目录树上的过程。==具体来说,挂载是将一个文件系统作为一个目录(即挂载点)的内容显示在另一个目录下的过程。通过挂载,用户可以访问该文件系统中的文件和目录,就好像它们是本地文件系统一样。挂载通常用于将磁盘分区、USB设备、网络文件系统等设备链接到操作系统的目录树中。例如,将一个USB闪存驱动器插入计算机时,操作系统可以自动挂载它并将它的文件系统显示在一个目录中。同样,当计算机通过网络连接到另一个计算机的文件系统时,操作系统也可以将该文件系统挂载到本地目录中,以便用户可以访问远程文件系统中的文件。

mount命令

mount命令是一个Linux/Unix命令,它用于将一个文件系统挂载到指定的挂载点(mount point)上,使得该文件系统可以被访问和使用。mount命令可以将本地文件系统、网络文件系统等挂载到指定的挂载点上。单纯的mount是查看已经挂载的详细信息。

最近刚刚接触这个技术,写的有些不足还请各位大佬指出,欢迎各位批评指教!!
在这里插入图片描述

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

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

相关文章

布谷鸟hash算法的并行化实现(一)

由于本人最近在写一个项目&#xff0c;为了实现数据查找以及数据修改部分的快速操作&#xff0c;所以采用hash对数据进行存储&#xff0c;而在此过程中接触到了布谷鸟hash&#xff0c;觉得这个hash算法还是很有意思并且高效&#xff0c;所以想着进行一些记录&#xff0c;本系列…

一文带你快速掌握如何读懂 YonBuilder移动开发 的项目源码

本文将通过四大步的简单讲述&#xff0c;让新手开发者朋友们快速掌握阅读YonBuilder移动开发项目源码的技巧方法。 1.读懂代码的第一步&#xff0c;了解项目的整体文件结构 CSS: 存放css样式的文件&#xff1b; feature&#xff1a;猜测是用来存放特征文件的&#xff0c;实际…

了解投影坐标系统,并在精美的地图上探索

投影坐标系简介 地球椭球体表面也是个曲面&#xff0c;而我们日常生活中的地图及量测空间通常是二维平面&#xff0c;因此在地图制图和线性量测时首先要考虑把曲面转化成平面。由于球面上任何一点的位置是用地理坐标&#xff08;λ&#xff0c;φ&#xff09;表示的&#xff0…

计算机三级网络技术总结(更新中)

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f35f;欢迎来到前端初见的博文&#xff0c;本文主要讲解我计算机三级网络技术&#x1f35f; &#x1f468;‍&#x1f527; 个人主页 : 前端初见 &#x1f95e;喜欢的朋友可以关注一下&#…

BEV专栏(二)从BEVFormer看BEV流程(下篇)

前言 书接上回&#xff0c;在上一篇文章中&#xff0c;我们介绍了BEVFormer这一先进的BEV算法。在本篇文章中&#xff0c;我们将深入探讨BEVFormer的实现细节&#xff0c;旨在帮助读者更深入地理解BEVFormer的工作原理和性能表现。 本教程禁止转载。同时&#xff0c;本教程来自…

【maven】自定义构建maven的jar包依赖

前言 自己定义自己的maven的jar包依赖&#xff0c;本地版本。 实现 pom.xml pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSche…

车载软件架构——闲聊几句AUTOSAR BSW(五)

我是穿拖鞋的汉子,魔都中坚持长期主义的工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 我们并不必要为了和谐,而时刻保持通情达理;我们需要具备的是,偶尔有肚量欣然承认在某些方面我们可能会有些不可理喻。该有主见的时候能掷地有声地镇得住场…

车载基础软件——基础软件验证平台(网络管理和诊断)

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 我们并不必要为了和谐&#xff0c;而时刻保持通情达理&#xff1b;我们需要具备的是&#xff0c;偶尔有肚量欣然承…

部署packstack及问题总结

目录 一、部署packstack 1.1 简介 1.2 性能搭配 1.3 准备工作 1.4 安装 二、出现的问题 2.1 安装中断临时文件 2.2 提示某个安装包出错 2.3 leatherman版本太高 三、安装成功 一、部署packstack 1.1 简介 对于openstack初学者而言&#xff0c;传统部署openstack流程…

MQ-rabbitMQ_基础篇

MQ-rabbitMQ_基础篇 1.MQ1.1什么是MQ1,2应用 2.常见消息中间件协议&#xff08;模型&#xff09;2.1JMS模型&#xff08;协议&#xff09;2.2AMQP协议 3.RabbitMQ3.1六种工作模式3.1.1Hello Word简单模式3.1.2word queues 工作队列能者多劳 3.1.3Publish/Subscribe 发布与订阅模…

在SwissTargetsPrediction数据库中预测成分靶点

1.对筛选的多肽成分进行靶点预测&#xff1a; ①用Uniport中的蛋白进行一系列操作&#xff08;水解&#xff0c;挑选2~8短肽&#xff0c;活性预测&#xff0c;毒性&#xff0c;过敏性预测&#xff0c;胃肠吸收度&#xff0c;半衰期和苦味的预测、生物活性功能预测&#xff09;…

mybatis连接池源码分析

文章目录 前言一、PooledDataSourceFactory二、获取连接三、归还连接 前言 其实大部分连接池的代码都大同小异&#xff0c;总体获取连接&#xff0c;归还连接逻辑大都相同。希望通过阅读本文章&#xff0c;能给你带来帮助。 测试用例 public void testMybatis()throws Excepti…

深入篇【C++】类与对象:运算符重载详解

深入篇【C】类与对象&#xff1a;运算符重载详解 ⏰一.运算符重载&#x1f553;1.<运算符重载&#x1f550;2.>运算符重载&#x1f552;3.运算符重载&#x1f551;4.运算符重载①.格式1.改进12.改进2 ②.默认成员函数1.功能2.不足 &#x1f553;5.<运算符重载&#x1…

学内核之十九:Linux文件系统结构大蓝图

目录 一&#xff1a;参考资料 二&#xff1a;整理的原因及基本原则 三&#xff1a;Linux文件系统大蓝图 四&#xff1a;补充说明 一&#xff1a;参考资料 博主梳理的关于文件系统的基础知识&#xff1a; 7.5 文件系统_定义_龙赤子的博客-CSDN博客 博主转载的关于page cac…

深入理解深度学习——正则化(Regularization):参数范数惩罚

分类目录&#xff1a;《深入理解深度学习》总目录 正则化在深度学习的出现前就已经被使用了数十年。线性模型&#xff0c;如线性回归和逻辑回归可以使用简单、直接、有效的正则化策略。许多正则化方法通过对目标函数 J J J添加一个参数范数惩罚 Ω ( θ ) \Omega(\theta) Ω(θ…

三、Neo4j 源码研究系列 - 持久化

version: v-2023051401 author: 路__ 说到数据库&#xff0c;那么离不开的模块就是持久化&#xff08;Persistence&#xff09;&#xff0c;数据持久化是数据库不可缺少的重要组成模块之一。可以说一个数据库少了持久化功能&#xff0c;可以说这个数据库就不足以称为数据库。…

并查集:解密算法面试中的常客

文章目录 1. 并查集原理&#x1f351; 举例说明&#x1f351; 并查集的应用 2. 并查集实现&#x1f351; 接口总览&#x1f351; 构造函数&#x1f351; 查询操作&#x1f345; 代码实现 &#x1f351; 合并操作&#x1f345; 动图演示&#x1f345; 代码实现 &#x1f351; 判…

Linux文件打开函数open()

#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> int main(void) {int fd -1; /*这个整数用来存放文件描述符*/char filename[] "good.txt"; /*打开的文件名&#xff0c;是一个字符数组…

String类 [下]

目录 一、拷贝构造和赋值重载的传统写法和现代写法 0x01 拷贝构造的传统写法 0x02 拷贝构造的现代写法 0x03 赋值重载的传统写法 0x04 赋值重载的现代写法 0x05 总结 二、 增删改查之后的string 0x01 成员函数swap: 0x02 reserve&#xff1a;改变容量 0x03 push_back: 尾…

带你深入理解Java异常

&#x1f495;“人生就像一盘棋&#xff0c;有时候你慢一步&#xff0c;就输掉了一局。但只要你不停止思考和行动&#xff0c;就永远有机会翻盘。”&#x1f495; &#x1f43c;作者&#xff1a;不能再留遗憾了&#x1f43c; &#x1f386;专栏&#xff1a;Java学习&#x1f38…