当前位置: 首页 > 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…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

《基于Apache Flink的流处理》笔记

思维导图 1-3 章 4-7章 8-11 章 参考资料 源码&#xff1a; https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

向量几何的二元性:叉乘模长与内积投影的深层联系

在数学与物理的空间世界中&#xff0c;向量运算构成了理解几何结构的基石。叉乘&#xff08;外积&#xff09;与点积&#xff08;内积&#xff09;作为向量代数的两大支柱&#xff0c;表面上呈现出截然不同的几何意义与代数形式&#xff0c;却在深层次上揭示了向量间相互作用的…...

Qt Quick Controls模块功能及架构

Qt Quick Controls是Qt Quick的一个附加模块&#xff0c;提供了一套用于构建完整用户界面的UI控件。在Qt 6.0中&#xff0c;这个模块经历了重大重构和改进。 一、主要功能和特点 1. 架构重构 完全重写了底层架构&#xff0c;与Qt Quick更紧密集成 移除了对Qt Widgets的依赖&…...

二叉树-144.二叉树的前序遍历-力扣(LeetCode)

一、题目解析 对于递归方法的前序遍历十分简单&#xff0c;但对于一位合格的程序猿而言&#xff0c;需要掌握将递归转化为非递归的能力&#xff0c;毕竟递归调用的时候会调用大量的栈帧&#xff0c;存在栈溢出风险。 二、算法原理 递归调用本质是系统建立栈帧&#xff0c;而非…...

AT模式下的全局锁冲突如何解决?

一、全局锁冲突解决方案 1. 业务层重试机制&#xff08;推荐方案&#xff09; Service public class OrderService {GlobalTransactionalRetryable(maxAttempts 3, backoff Backoff(delay 100))public void createOrder(OrderDTO order) {// 库存扣减&#xff08;自动加全…...