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

Linux 的 sysfs 伪文件系统介绍【用户可以通过文件操作与内核交互(如调用内核函数),而无需编写内核代码】

1. 什么是 sysfs伪文件系统?

sysfs 是 Linux 内核提供的 伪文件系统,用于向用户空间暴露内核对象的信息和控制接口。它是 procfs 的补充,主要用于管理 设备、驱动、内核子系统 等信息,使用户可以通过文件操作(如用户空间中的open函数、write函数、read函数、 cat命令、echo命令)与内核交互【对文件的操作其实直接转换为调用相应的内核函数】,而无需编写内核代码。

  • 挂载位置:通常挂载在 /sys 目录下。
  • 作用
    • 提供系统信息(如 CPU、设备、驱动程序、总线)。
    • 提供设备控制接口(如 GPIO、PWM、I2C、SPI 等)。
    • 支持热插拔设备管理(如 USB、PCI、SATA 设备)。

sysfs伪文件系统实际上和设备文件很类似,它们都是用户空间与内核空间交互的媒介,不同的是设备文件是内核空间中驱动程序中的概念,而sysfs伪文件系统则是内核空间中别的需要向用户空间暴露的内核对象的信息和控制接口。所以它的使用实际上和设备文件很类似。

在终端中使用sysfs伪文件系统时,表面上我们是在用相关函数或catecho命令进行读或写相关的文件,实际上会转换为对某个内核函数的调用。具体的例子见本篇博文后面列出的“一个实际的例子分析”
而在程序代码中使用sysfs伪文件系统时,就和操作设备文件差不多。具体的例子见 https://blog.csdn.net/wenhao_ir/article/details/145459006【搜索“led_init(void)”】


2. sysfs 的目录结构

sysfs 目录下的结构主要分为以下几部分:

/sys/├── block/            # 块设备(如磁盘、分区)├── bus/              # 设备总线(如 i2c, usb, spi, pci, platform)├── class/            # 设备类(如 gpio, net, tty, input)├── devices/          # 设备层次结构├── firmware/         # 固件接口├── kernel/           # 内核参数├── module/           # 加载的内核模块└── power/            # 电源管理

3. sysfs 目录详解

(1)/sys/class/

  • 组织 设备 按类别分类(如 GPIO、网络、输入设备)。

  • 例子:

    ls /sys/class/
    

    输出:

    gpio/   net/   input/   sound/   thermal/   tty/   usb_device/
    
  • GPIO 设备(使用 sysfs 方式操作 GPIO)

    echo 131 > /sys/class/gpio/export    # 申请 GPIO 131
    echo out > /sys/class/gpio/gpio131/direction   # 设置方向
    echo 1 > /sys/class/gpio/gpio131/value   # 设为高电平
    

    我后面会对这三句命令作详细解释,其实就是以这三句命令活生生地展现 sysfs 伪文件系统是怎么实现与内核的交互的。

  • 网卡信息

    ls /sys/class/net/
    eth0  lo  wlan0
    
    • cat /sys/class/net/eth0/address # 查看 MAC 地址
    • cat /sys/class/net/eth0/statistics/rx_bytes # 接收的字节数

(2)/sys/bus/

  • 组织 设备按总线分类(如 PCI、USB、I2C、SPI)。

  • 例子:

    ls /sys/bus/
    

    输出:

    i2c/   pci/   platform/   scsi/   spi/   usb/
    
    • /sys/bus/i2c/devices/ # I2C 设备
    • /sys/bus/usb/devices/ # USB 设备
    • /sys/bus/pci/devices/ # PCI 设备
  • 示例:列出所有 USB 设备

    ls /sys/bus/usb/devices/
    

(3)/sys/devices/

  • 设备拓扑结构 组织设备信息(如 /sys/devices/pci0000:00/0000:00:1f.2/)。

  • 例子:

    ls /sys/devices/
    
    system/  virtual/  pci0000:00/
    
  • 查看 CPU 信息

    cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    

(4)/sys/module/

  • 显示 已加载的内核模块 及其参数。
  • 例子:
    ls /sys/module/
    
    • cat /sys/module/gpio/parameters/
    • cat /sys/module/usbcore/parameters/autosuspend

(5)/sys/kernel/

  • 提供与 内核相关的配置信息

  • 例子:

    ls /sys/kernel/
    
    debug/   security/   tracing/
    
  • 查看系统调试信息

    cat /sys/kernel/debug/gpio
    

4. sysfs 的工作机制

  • sysfs 由 kobjectkset 组成
    • kobject 代表 内核对象(如设备、驱动)。
    • ksetkobject 的集合(如 devicesbus)。
  • 设备驱动注册时,sysfs 自动创建目录和文件
  • 用户空间可以通过 catecho 直接访问内核数据

示例:
设备驱动代码:

static struct class *my_class;
my_class = class_create(THIS_MODULE, "my_device");
device_create(my_class, NULL, MKDEV(200, 0), NULL, "mydev0");

sysfs 生成的目录:

/sys/class/my_device/mydev0/

5. sysfs 的优缺点

优点缺点
允许用户空间与内核交互只能操作文本,效率低
结构清晰,按类别组织不适用于高频操作
可用于设备驱动调试已被 libgpiod 等替代

6. sysfs 与 udev、procfs 的区别

文件系统作用特点
sysfs (/sys/)设备、驱动、总线信息设备管理,与 kobject 相关
procfs (/proc/)进程、内核信息进程管理,虚拟文件
udev (/dev/)设备文件动态创建 /dev/ 设备节点

7. 结论

  • sysfs 是 Linux 设备模型的核心部分,用于暴露设备和驱动信息。
  • 用户空间可以直接 cat 读取信息,echo 进行控制,简化了驱动开发。
  • sysfs 已逐渐被 libgpiodudev 替代,但仍然广泛使用,特别是在嵌入式系统中。

8.一个实际的例子分析

我们可以通过下面的三条命令实现将编号为131的GPIO口(GPIO5_IO03)的值设为逻辑1值,如果GPIO没有被标记为低电平有效,则逻辑1值就是物理上的高电平,否则就是物理上的低电平,在这里,我实测了一下,GPIO5_IO03并没有被标记为低电平有效。即运行完成后在下面的原理图基础上,灯灭了。
在这里插入图片描述

echo 131 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio131/direction
echo 1 > /sys/class/gpio/gpio131/value

这三条命令是通过 sysfs 接口 操作 GPIO 口 131,本质上是用户空间通过 echo 命令向 sysfs 伪文件系统写入数据,触发内核的 GPIO 相关操作【实际上就是去调用内核中的相关GPIO子系统的函数】。

在看下面的分析前可以参考下博文 https://blog.csdn.net/wenhao_ir/article/details/145119224 是如何利用GPIO子系统实现LED灯的驱动的,实际上这篇博文中调用的函数也就是下面三条echo命令触发的内核函数。


1. echo 命令与 sysfs GPIO 实现的关系

echo 命令的作用是 向文件写入内容,但当目标文件是 sysfs 文件时,写入的值会被内核的 GPIO 处理函数拦截,并执行相应的 GPIO 操作。

下面具体分析你的 echo 命令是如何作用到 GPIO 上的:

(1)导出 GPIO

echo 131 > /sys/class/gpio/export
  • 作用:请求使用 GPIO 131,让内核创建 /sys/class/gpio/gpio131/ 目录。

  • sysfs 机制

    1. echo 131 > /sys/class/gpio/export 相当于向 export 文件 写入 131
    2. 内核中的 export_store() 处理该写入,并调用 gpio_request(131, NULL) 申请 GPIO 资源。
    3. 申请成功后,内核会创建 /sys/class/gpio/gpio131/ 目录,用于控制 GPIO 131。
  • 相关的内核代码(在 drivers/gpio/gpiolib-sysfs.c 中):

    static ssize_t export_store(struct class *class,struct class_attribute *attr,const char *buf, size_t count)
    {int gpio;int ret;ret = kstrtoint(buf, 0, &gpio);if (ret)return ret;ret = gpio_request(gpio, NULL);if (ret)return ret;return count;
    }
    

(2)设置 GPIO 方向

echo out > /sys/class/gpio/gpio131/direction
  • 作用:设置 GPIO 131 为 输出模式

  • sysfs 机制

    1. echo out > /sys/class/gpio/gpio131/direction 相当于向 direction 文件 写入字符串 "out"
    2. gpio_direction_output(131, 0) 被调用,将 GPIO 131 配置为 输出模式(初始值 0)。
    3. 内核 GPIO 驱动最终会调用 gpio_chip->direction_output() 这个函数,该函数是具体的 GPIO 控制器驱动 提供的,执行底层的寄存器操作,配置 GPIO 方向。
  • 相关的内核代码(在 drivers/gpio/gpiolib-sysfs.c 中):

    static ssize_t direction_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
    {struct gpio_desc *desc = dev_get_drvdata(dev);if (!strncmp(buf, "out", 3))gpiod_direction_output(desc, 0);elsegpiod_direction_input(desc);return count;
    }
    

(3)设置 GPIO 输出值

echo 1 > /sys/class/gpio/gpio131/value
  • 作用:设置 GPIO 131 输出 高电平(1)

  • sysfs 机制

    1. echo 1 > /sys/class/gpio/gpio131/valuevalue 文件 写入 "1"
    2. gpio_set_value(131, 1) 被调用,更新 GPIO 131 的输出电平。
    3. 底层驱动gpio_chip->set())负责具体的寄存器操作,将 GPIO 置高。
  • 相关的内核代码(在 drivers/gpio/gpiolib-sysfs.c 中):

    static ssize_t value_store(struct device *dev,struct device_attribute *attr,const char *buf, size_t count)
    {struct gpio_desc *desc = dev_get_drvdata(dev);int value;if (buf[0] == '0')value = 0;elsevalue = 1;gpiod_set_value(desc, value);return count;
    }
    

2. sysfs GPIO 实现的局限

虽然 sysfs 提供了一种 简单的方式 来访问 GPIO,但它有以下局限性:

  1. 效率低:sysfs 通过文件操作控制 GPIO,比 ioctlmmap 慢。
  2. 无法高效处理中断:sysfs 方式不适合监听 GPIO 变化(如按键)。
  3. 已被 libgpiod 取代:新版本的 Linux 内核推荐使用 libgpiod(基于 ioctl 的 GPIO 操作)。

3. 结论

🔹 sysfs 方式是 Linux 早期的 GPIO 控制方法,echo 命令本质上是向 sysfs 伪文件系统写入数据,触发内核调用 GPIO 操作函数。
🔹 每个 echo 命令最终都会调用 gpiolib 提供的 API,如 gpio_request()gpio_direction_output()gpio_set_value(),再由底层 GPIO 驱动完成实际的硬件操作。
🔹 sysfs 方式简单直观,但不适用于高效 GPIO 访问,现代 Linux 推荐使用 libgpiod 代替 sysfs GPIO。(实际上在Linux 5.10以上版本中已经把sysfs这种对GPIO的操作方式废弃了)
比如上面的三条命令等效于下面这条gpiod API的命令:

gpioset gpiochip0 131=1

相关文章:

Linux 的 sysfs 伪文件系统介绍【用户可以通过文件操作与内核交互(如调用内核函数),而无需编写内核代码】

1. 什么是 sysfs伪文件系统? sysfs 是 Linux 内核提供的 伪文件系统,用于向用户空间暴露内核对象的信息和控制接口。它是 procfs 的补充,主要用于管理 设备、驱动、内核子系统 等信息,使用户可以通过文件操作(如用户空…...

每日一题洛谷P5721 【深基4.例6】数字直角三角形c++

#include<iostream> using namespace std; int main() {int n;cin >> n;int t 1;for (int i 0; i < n; i) {for (int j 0; j < n - i; j) {printf("%02d",t);t;}cout << endl;}return 0; }...

计算机网络笔记再战——理解几个经典的协议1

目录 前言 从协议是什么出发 关于TCP/IP协议体系 几个传输方式的分类 地址 网卡 中继器&#xff08;Repeater&#xff09; 网桥&#xff08;Bridge&#xff09; 路由器&#xff08;Router&#xff09; 网关 前言 笔者最近正在整理&#xff08;笔者开的坑不少&#xf…...

ElasticSearch学习笔记-解析JSON格式的内容

如果需要屏蔽其他项目对Elasticsearch的直接访问操作&#xff0c;统一由一个入口访问操作Elasticsearch&#xff0c;可以考虑直接传入JSON格式语句解析执行。 相关依赖包 <properties><elasticsearch.version>7.9.3</elasticsearch.version><elasticsea…...

浅谈密码相关原理及代码实现

本代码仅供学习、研究、教育或合法用途。开发者明确声明其无意将该代码用于任何违法、犯罪或违反道德规范的行为。任何个人或组织在使用本代码时&#xff0c;需自行确保其行为符合所在国家或地区的法律法规。 开发者对任何因直接或间接使用该代码而导致的法律责任、经济损失或…...

Spring Boot常用注解深度解析:从入门到精通

今天&#xff0c;这篇文章带你将深入理解Spring Boot中30常用注解&#xff0c;通过代码示例和关系图&#xff0c;帮助你彻底掌握Spring核心注解的使用场景和内在联系。 一、启动类与核心注解 1.1 SpringBootApplication 组合注解&#xff1a; SpringBootApplication Confi…...

can not add outlook new accounts on the outlook

link : Reference url...

私有化部署 DeepSeek + Dify,构建你的专属私人 AI 助手

私有化部署 DeepSeek Dify&#xff0c;构建你的专属私人 AI 助手 概述 DeepSeek 是一款开创性的开源大语言模型&#xff0c;凭借其先进的算法架构和反思链能力&#xff0c;为 AI 对话交互带来了革新性的体验。通过私有化部署&#xff0c;你可以充分掌控数据安全和使用安全。…...

【Elasticsearch】post_filter

post_filter是 Elasticsearch 中的一种后置过滤机制&#xff0c;用于在查询执行完成后对结果进行过滤。以下是关于post_filter的详细介绍&#xff1a; 工作原理 • 查询后过滤&#xff1a;post_filter在查询执行完毕后对返回的文档集进行过滤。这意味着所有与查询匹配的文档都…...

验证工具:GVIM和VIM

一、定义与关系 gVim&#xff1a;gVim是Vim的图形界面版本&#xff0c;提供了更多的图形化功能&#xff0c;如菜单栏、工具栏和鼠标支持。它使得Vim的使用更加直观和方便&#xff0c;尤其对于不习惯命令行界面的用户来说。Vim&#xff1a;Vim是一个在命令行界面下运行的文本编…...

如何优化垃圾回收机制?

垃圾回收机制 掌握 GC 算法之前&#xff0c;我们需要先弄清楚 3 个问题。第一&#xff0c;回收发生在哪里&#xff1f;第二&#xff0c;对象在 什么时候可以被回收&#xff1f;第三&#xff0c;如何回收这些对象&#xff1f; 回收发生在哪里&#xff1f; JVM 的内存区域中&…...

beyond the ‘PHYSICAL‘ memory limit.问题处理

Container [pid5616,containerIDcontainer_e50_1734408743176_3027740_01_000006] is running 507887616B beyond the ‘PHYSICAL’ memory limit. Current usage: 4.5 GB of 4 GB physical memory used; 6.6 GB of 8.4 GB virtual memory used. Killing container. 1.增大map…...

Day36【AI思考】-表达式知识体系总览

文章目录 **表达式知识体系总览**回答1&#xff1a;**表达式知识体系****一、三种表达式形式对比****二、表达式转换核心方法****1. 中缀转后缀&#xff08;重点&#xff09;****2. 中缀转前缀** **三、表达式计算方法****1. 后缀表达式计算&#xff08;栈实现&#xff09;****…...

段错误(Segmentation Fault)调试

1. 使用 GDB&#xff08;GNU Debugger&#xff09; GDB 是一个强大的调试工具&#xff0c;可以帮助你逐步执行程序并检查变量状态。 编译时添加调试信息&#xff1a; gcc -g your_program.c -o your_program启动 GDB&#xff1a; gdb ./your_program运行程序&#xff1a; …...

每日Attention学习19——Convolutional Multi-Focal Attention

每日Attention学习19——Convolutional Multi-Focal Attention 模块出处 [ICLR 25 Submission] [link] UltraLightUNet: Rethinking U-shaped Network with Multi-kernel Lightweight Convolutions for Medical Image Segmentation 模块名称 Convolutional Multi-Focal Atte…...

LeetCode题练习与总结:三个数的最大乘积--628

一、题目描述 给你一个整型数组 nums &#xff0c;在数组中找出由三个数组成的最大乘积&#xff0c;并输出这个乘积。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;6示例 2&#xff1a; 输入&#xff1a;nums [1,2,3,4] 输出&#xff1a;24示例 3&a…...

Colorful/七彩虹 隐星P15 TA 24 原厂Win11 家庭版系统 带F9 Colorful一键恢复功能

Colorful/七彩虹 隐星P15 TA 24 原厂Win11 家庭中文版系统 带F9 Colorful一键恢复功能 自动重建COLORFUL RECOVERY功能 带所有随机软件和机型专用驱动 支持机型&#xff1a;隐星P15 TA 24 文件下载&#xff1a;asusoem.cn/745.html 文件格式&#xff1a;ISO 系统版本&…...

第二篇:多模态技术突破——DeepSeek如何重构AI的感知与认知边界

——从跨模态对齐到因果推理的工程化实践 在AI技术从单一模态向多模态跃迁的关键阶段&#xff0c;DeepSeek通过自研的多模态融合框架&#xff0c;在视觉-语言-语音的联合理解与生成领域实现系统性突破。本文将从技术实现层面&#xff0c;解构其跨模态表征学习、动态融合机制与…...

CTreeCtrl 设置图标

mfc界面修改真难受 使用CTreeCtrl 进行设置导航视图时&#xff0c;有时候需要设置图标&#xff0c;一般使用如下代码 m_TreeViewImages.DeleteImageList();UINT uiBmpId IDB_ICONLIST_TREE;CBitmap bmp; if (!bmp.LoadBitmap(uiBmpId)) return;BITMAP bmpObj; bmp.GetBitmap…...

在JAX-RS中获取请求头信息的方法

在JAX-RS中获取请求头信息的方法 HeaderParam注解&#xff0c;可以直接将请求头中的特定值注入到方法参数中&#xff0c;代码示例&#xff1a; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.Path; import javax.ws.rs.core.Response;Path(&q…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

SpringTask-03.入门案例

一.入门案例 启动类&#xff1a; package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...