0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

linux--sysfs文件系统

Rice嵌入式开发技术分享 来源:Rice嵌入式 作者:Rice嵌入式 2024-07-08 11:37 次阅读

sysfs文件系统

sysfs,全称为System Filesystem,是一个由Linux内核实现的虚拟文件系统。它扮演着一个桥梁的角色,将内核中的设备和驱动程序信息以文件的形式呈现给用户空间。与/proc文件系统相似,sysfs专注于展示设备和驱动程序的细节,而/proc则主要反映进程信息。

在sysfs中,信息被组织成层次化的文件系统结构。每个设备或内核对象在文件系统中都有其对应的表示,通常是以文件或目录的形式存在。这些文件不仅存储了设备的属性和状态信息,而且很多文件还允许用户通过读写操作来对设备进行配置或控制。

sysfs默认挂载在文件系统的/sys路径下。通过这个虚拟文件系统,用户空间的应用程序能够以一种直观和动态的方式访问和管理系统设备,无需进行复杂的内核空间交互。这种设计提供了一种高效且用户友好的接口,使得设备管理变得更加简单和灵活。

kernel Object

在Linux内核架构中,kobject扮演着一个核心角色,它是一个用于抽象化内核对象的框架。kobject不仅构成了内核中各种子系统的基础构件,而且能够代表设备、驱动程序、总线等多样化的内核实体。

kobject架构提供了一种灵活且统一的模型,用以维护和管理内核对象。每个Kobject实例都拥有一个独一无二的标识符和指向其上层Kobject的链接,这样的设计允许它们形成一个有序的层级网络。更进一步,Kobject可以附加多种属性,这些属性反映了对象的特征或状态,并且可以通过sysfs这一虚拟文件系统对外公布,使得用户空间程序能够访问和操作这些属性。

Sysfs作为Kobject信息呈现的媒介,将内核内部的设备和驱动程序等对象的状态和信息以文件的形式展现给用户空间。每当内核中新增设备或驱动程序时,相应的Kobject实例也会被动态创建,并通过Sysfs将这些信息映射到用户空间可访问的路径下。

在Linux内核的源码树中,struct kobject这一数据结构在"linux/kobject.h"头文件里定义。它经常作为其他结构体的成员出现,使得这些结构体所代表的内核对象能够整合进Kobject的管理体系中。通过这种方式,内核开发者可以轻松地为各种内核对象实现统一的管理和访问接口。

structkobject{
constchar*name;
structlist_headentry;
structkobject*parent;
structkset*kset;
structkobj_type*ktype;
structkernfs_node*sd;/*sysfsdirectoryentry*/
structkrefkref;
...
};

其中:- kref:提供kobject的引用技术。- ktype:kobject关联的类型。- kset:指向同一类kobject集合的指针。- sd:当前kobject在/sys下的目录条目。

sysfs使用方式

Linux内核中使用sysfs的步骤比较简单:(1)在sys路径下创建目录;(2)创建sysfs文件。下面将详细展开这两步涉及的内核API

在sys下创建目录

structkobject*kobject_create_and_add(constchar*name,structkobject*parent);

Linux内核预定义了几个常用的parent参数:- kernel_kobj:在/sys/kernel下创建目录;- firmware_kobj:在/sys/firmware下创建目录;- fs_kobj:在/sys/fs下创建目录。- 如果parent取值为NULL,则在/sys下面创建目录。

相应地,如果需要删除对应的sysfs目录,可以用:

voidkobject_put(structkobject*kobj);

创建sysfs文件

sysfs文件可以通过sysfs属性来创建,它定义在头文件"sysfs.h"中:

structkobj_attribute{
structattributeattr;
ssize_t(*show)(structkobject*kobj,structkobj_attribute*attr,char*buf);
ssize_t(*store)(structkobject*kobj,structkobj_attribute*attr,constchar*buf,size_tcount);
};

attr表示将要创建的文件(属性),而show和store分别表示对应的sysfs文件在读和写操作时的回调函数。

struct kobj_attribute可以通过__ATTR宏来创建:

__ATTR(name,permission,show_ptr,store_ptr);

准备好attr之后,可以通过sysfs_create_file来创建出sysfs文件:

intsysfs_create_file(structkobject*kobj,conststructattribute*attr);

如果需要删除对应的sysfs文件,可以用:

voidsysfs_remove_file(structkobject*kobj,conststructattribute*attr);

sysfs创建设备节点

前面描述了如何创建一个基本的sysfs,接下载描述的是如何创建设备节点的sysfs。

实际创建设备节点的sysf跟基本的sysfs是一样的,只是结构体换了一个名字。它使用DEVICE_ATTR宏,可以定义一个struct device_attribute设备属性,使用sysfs_create_file便可以在设备目录下创建具有show和store方法的节点。

DEVICE_ATTR宏定义

DEVICE_ATTR宏定义如下:

#defineDEVICE_ATTR(_name,_mode,_show,_store)
structdevice_attributedev_attr_##_name=__ATTR(_name,_mode,_show,_store)

__ATTR宏定义,宏定义在include/linux/sysfs.h文件中,如下:

#define__ATTR(_name,_mode,_show,_store){
.attr={.name=__stringify(_name),
.mode=VERIFY_OCTAL_PERMISSIONS(_mode)},
.show=_show,
.store=_store,
}

struct device_attribute结构体,该结构体的定义在include /linux/device.h,其定义如下:

structdevice_attribute{
structattributeattr;
ssize_t(*show)(structdevice*dev,structdevice_attribute*attr,
char*buf);
ssize_t(*store)(structdevice*dev,structdevice_attribute*attr,
constchar*buf,size_tcount);
};

struct attribute结构体, 该结构体的定义在include /linux/device.h,其定义如下:

structattribute{
constchar*name;
umode_tmode;
#ifdefCONFIG_DEBUG_LOCK_ALLOC
boolignore_lockdep:1;
structlock_class_key*key;
structlock_class_keyskey;
#endif
};

DEVICE_ATTR宏定义等价说明

我们顶一个文件的范式如下

DEVICE_ATTR(_name,_mode,_show,_store)

等价于:

structdevice_attributedev_attr_##_name={
.attr={.name=__stringify(_name),
.mode=VERIFY_OCTAL_PERMISSIONS(_mode)},
.show=_show,
.store=_store,
}

show函数的详细描述:

ssize_t(*show)(structdevice*dev,structdevice_attribute*attr,char*buf);

参数说明:

入参buf是需要我们填充的string即我们cat属性节点时要显示的内容;-函数的返回值是我们填充buf的长度,且长度应当小于一个页面的大小(4096字节);

其他参数一般不用关心。

实例说明,当我们使用cat命令的时候,将调用该函数

staticssize_tshow_youyeetoo_device(structdevice*dev,
structdevice_attribute*attr,char*buf)
{
returnsprintf(buf,"%sn",mybuf);
}

store函数的详细描述:

ssize_t(*store)(structdevice*dev,structdevice_attribute*attr,constchar*buf,size_tcount);

参数说明:

入参buf是用户传入的字符串,即echo到属性节点的内容;

入参count是buf中字符串的长度。

函数的返回值通常返回count即可。

其他参数一般不用关心。

实例说明,当我们使用echo命令的时候,将调用该函数:

staticssize_tstore_youyeetoo_device(structdevice*dev,
structdevice_attribute*attr,
constchar*buf,size_tcount)
{
sprintf(mybuf,"%s",buf);
returncount;
}

mode的权限定义,在kernel/include/uapi/linux/stat.h中:

#defineS_IRWXU00700//用户可读写和执行
#defineS_IRUSR00400//用户可读
#defineS_IWUSR00200//用户可写
#defineS_IXUSR00100//用户可执行

#defineS_IRWXG00070//用户组可读写和执行
#defineS_IRGRP00040//用户组可读
#defineS_IWGRP00020//用户组可写
#defineS_IXGRP00010//用户组可执行

#defineS_IRWXO00007//其他可读写和执行
#defineS_IROTH00004//其他可读
#defineS_IWOTH00002//其他可写
#defineS_IXOTH00001//其他可执行

至此,我们已经定义好了.show和.store函数,那么就可以使用DEVICE_ATTR了。

staticDEVICE_ATTR(youyeetoo_device,S_IWUSR|S_IRUSR,show_youyeetoo_device,store_youyeetoo_device);

device attribute添加到sysfs

上面描述的是sysfs的读写接口的定义方式,他还需要注册到sysfs中。才会在对应驱动中显示我们的文件,其中:

注册函数:sysfs_create_file();

注销函数:sysfs_remove_file();

样例代码代码:

注册样例:

sysfs_create_file(&(youyeetoo_dev->kobj),&dev_attr_youyeetoo.attr);

注销样例:

sysfs_remove_file(&(youyeetoo_dev->kobj),&dev_attr_youyeetoo.attr);

sysfs样例测试

完整的测试代码,在sysfs的驱动节点里面生成一个youyeetoo文件,文件支持读写功能。

#include
#include
#include
#include
#include

staticintmajor;
staticstructclass*youyeetoo_class;
structdevice*youyeetoo_dev;
staticcharyouyeetoo_buff[100]="youyeetoo";

staticssize_tshow_youyeetoo_device(structdevice*dev,
structdevice_attribute*attr,char*buf)
{
returnsprintf(buf,"%sn",youyeetoo_buff);
}

staticssize_tstore_youyeetoo_device(structdevice*dev,
structdevice_attribute*attr,
constchar*buf,size_tcount)
{
sprintf(youyeetoo_buff,"%s",buf);
returncount;
}
staticDEVICE_ATTR(youyeetoo,S_IWUSR|S_IRUSR,show_youyeetoo_device,store_youyeetoo_device);

structfile_operationsyouyeetoo_ops={
.owner=THIS_MODULE,
};

staticintyouyeetoo_init(void)
{
major=register_chrdev(0,"youyeetoo",&youyeetoo_ops);
youyeetoo_class=class_create(THIS_MODULE,"youyeetoo");
youyeetoo_dev=device_create(youyeetoo_class,0,MKDEV(major,0),NULL,"youyeetoo");
if(sysfs_create_file(&(youyeetoo_dev->kobj),&dev_attr_youyeetoo.attr))
{//在mytest_device设备目录下创建一个sys_device_file属性文件
return-1;
}

return0;
}

staticvoidyouyeetoo_exit(void)
{
device_destroy(youyeetoo_class,MKDEV(major,0));
class_destroy(youyeetoo_class);
unregister_chrdev(major,"youyeetoo");
sysfs_remove_file(&(youyeetoo_dev->kobj),&dev_attr_youyeetoo.attr);
}

module_init(youyeetoo_init);
module_exit(youyeetoo_exit);
MODULE_AUTHOR("youyeetoo");
MODULE_LICENSE("GPL");

将上面驱动编译烧录之后,就可以sysfs下看到我们创建的文件:

4ccf9d98-3bf9-11ef-82a0-92fbcf53809c.png

测试我们创建的sysfs

4cdd524e-3bf9-11ef-82a0-92fbcf53809c.png

4ce0f1ec-3bf9-11ef-82a0-92fbcf53809c.png

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Linux
    +关注

    关注

    87

    文章

    11116

    浏览量

    207752
  • Sysfs
    +关注

    关注

    0

    文章

    15

    浏览量

    6228
收藏 人收藏

    评论

    相关推荐

    【AWorks试用体验】使用sysfs文件系统 控制IED(1) Shell 点亮LED

    在嵌入式设备中控制GPIO 一般做法是通过写一个单独的驱动程序。而大多数资料显示都是使用这一种方法。 但其实Linux下有一个通用的 GPIO 控制接口, 就是 sysfs文件系统什么是sys
    发表于 08-16 19:17

    Linux文件系统课程

    本章学习目标理解什么是文件系统了解文件系统工作原理理解Fedora Core Linux文件系统的结构掌握Fedora Core Linux
    发表于 04-10 17:07 0次下载

    Linux文件系统简介

    Linux文件系统简介 什么是根文件   根文件系统首先是一种文件系统,但是相对于普通的文件系统
    发表于 04-21 17:01 5083次阅读

    玩转Linux,先把文件系统搞懂

    Linux 支持多种文件系统,包括 ext2 、 ext3 、 vfat 、 ntfs 、 iso9660 、 jffs 、 romfs 和 nfs 等,为了对各类文件系统进行统一管理, Li
    发表于 08-16 10:50 2009次阅读
    玩转<b class='flag-5'>Linux</b>,先把<b class='flag-5'>文件系统</b>搞懂

    Linux设备驱动开发详解》第5章、Linux文件系统与设备文件系统

    Linux设备驱动开发详解》第5章、Linux文件系统与设备文件系统
    发表于 10-27 14:13 0次下载
    《<b class='flag-5'>Linux</b>设备驱动开发详解》第5章、<b class='flag-5'>Linux</b><b class='flag-5'>文件系统</b>与设备<b class='flag-5'>文件系统</b>

    Linux 内核/sys 文件系统介绍

    linux2.6内核引入sysfs文件系统sysfs可以看成与proc,devfs和devpty同类别的文件系统,该
    发表于 04-25 16:20 4206次阅读
    <b class='flag-5'>Linux</b> 内核/sys <b class='flag-5'>文件系统</b>介绍

    学会使用Linux 文件系统:procfs, sysfs, debugfs

    sysfs 中,有另外一个常见用法,那就是在一个 kobject 对应的目录下创建一个符号(属性文件)指向另外一个 kobject 对应的目录,通常这个是为了方便记忆和访问。这个API是 sysfs_create_link。
    发表于 04-25 17:19 1152次阅读

    可以了解的Linux 文件系统结构

    Linux中的文件是什么?它的文件系统又是什么?那些配置文件又在哪里?我下载好的程序保存在哪里了?在 Linux
    发表于 04-27 14:06 665次阅读
    可以了解的<b class='flag-5'>Linux</b> <b class='flag-5'>文件系统</b>结构

    Linux最新UBI文件系统介绍

    嵌入式linux中文站关注嵌入式linux文件系统的发展。在linux-2.6.27以前,谈到Flash文件系统,大家很多时候多会想到cra
    发表于 04-27 19:37 6310次阅读

    linux文件系统中的虚拟文件系统设计详解

    Linux 中允许众多不同的文件系统共存,如 ext2, ext3, vfat 等。通过使用同一套文件 I/O 系统 调用即可对 Linux
    发表于 04-02 14:37 1716次阅读
    <b class='flag-5'>linux</b><b class='flag-5'>文件系统</b>中的虚拟<b class='flag-5'>文件系统</b>设计详解

    Linux设备模型:sysfs

    sysfs是一个基于RAM的文件系统,它和Kobject一起,可以将Kernel的数据结构导出到用户空间,以文件目录结构的形式,提供对这些数据结构(以及数据结构的属性)的访问支持。
    发表于 05-12 09:50 1338次阅读

    Linux文件系统解析

    Linux 中,最直观、最可见的部分就是 文件系统(file system)。下面我们就来一起探讨一下关于 Linux 中国的文件系统系统
    的头像 发表于 09-16 11:29 2363次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>文件系统</b>解析

    Linux文件系统与持久性内存

    1、Linux 虚拟文件系统介绍 在 Linux 系统中一切皆文件,除了通常所说的狭义的文件以外
    的头像 发表于 11-26 14:34 2415次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>文件系统</b>与持久性内存

    适用于Linux的最佳通用文件系统 Linux文件系统的安装

    为您的计算机选择正确的文件系统可能是一个困难的过程。您可能会想知道:为什么文件系统很重要?有没有适用于安装 Linux 的特定文件系统? 事实证明,有两种
    发表于 08-03 10:22 283次阅读
    适用于<b class='flag-5'>Linux</b>的最佳通用<b class='flag-5'>文件系统</b> <b class='flag-5'>Linux</b><b class='flag-5'>文件系统</b>的安装

    Linux文件系统特点

    Linux文件系统特点 文件系统要有严格的组织形式,使得文件能够以块为单位进行存储。 文件系统中也要有索引区,用来方便查找一个
    的头像 发表于 11-09 14:48 946次阅读
    <b class='flag-5'>Linux</b>的<b class='flag-5'>文件系统</b>特点