如何在Linux系统中使用sysfs?

在这里插入图片描述

🥇今日学习目标:如何在Linux系统中使用sysfs
🤵‍♂️ 创作者:JamesBin
⏰预计时间:10分钟
🎉个人主页:嵌入式悦翔园个人主页
🍁专栏介绍:Linux驱动开发100问

一、前言

sysfs是一种文件系统,它允许用户和内核使用文件的方式来交互。sysfs通常用于与设备驱动程序交互,以便用户可以更改驱动程序的行为或访问有关驱动程序状态的信息。在本文中,我们将介绍如何在Linux系统中使用sysfs。

二、sysfs概述

sysfs是一种虚拟文件系统,它将系统中的设备、驱动程序和其他内核对象表示为文件和目录。sysfs通常被挂载到/sys目录中,其中每个设备和驱动程序都具有唯一的目录。每个目录中包含多个文件,用于控制设备的行为或提供有关设备状态的信息。

sysfs的主要目的是为了方便内核开发人员和设备驱动程序编写者进行交互。sysfs中的每个文件都有一个相关的内核对象,例如一个设备、一个总线或一个驱动程序。当用户或程序读取或写入sysfs文件时,内核会相应地更改相关的内核对象。

三、sysfs文件系统的挂载和卸载

sysfs文件系统是由内核自动挂载的,无需手动挂载。当系统启动时,内核会自动将sysfs文件系统挂载到/sys目录中。如果您需要手动卸载sysfs文件系统,可以使用以下命令:

sudo umount /sys

sysfs中的文件用于控制设备的行为或提供有关设备状态的信息。sysfs中的文件通常是只读的,但有些文件也可以被写入以改变设备的状态或行为。sysfs中的每个文件都有一个唯一的路径,以设备或驱动程序的名称和文件名表示。

例如,要查看/sys目录下以太网设备的状态信息,可以使用以下命令:

cat /sys/class/net/eth0/operstate

在这个例子中,/sys/class/net/eth0是以太网设备的目录,operstate是设备的状态文件。通过读取这个文件,可以获取以太网设备的当前状态,例如 updown

另一个示例是要修改设备的状态。要启用或禁用以太网设备,可以使用以下命令:

echo "up" > /sys/class/net/eth0/operstate

这个命令将以太网设备的状态设置为 up ,即启用设备。要禁用设备,只需将 up 更改为 down

四、sysfs文件系统的目录结构

sysfs文件系统提供了一种以层次结构形式组织系统信息的方式。在sysfs中,每个设备和驱动程序都表示为一个目录,目录中包含一些属性文件和其他目录,这些文件和目录可以用于控制和监视设备。

sysfs文件系统的根目录位于/sys下,其中的目录结构如下:

  • /sys/block: 存放块设备的目录,包括硬盘、U盘等。
  • /sys/bus: 存放总线类型目录的地方,每种总线都有一个目录,如pci、usb、spi等。
  • /sys/class: 存放设备类目录的地方,每种设备类都有一个目录,如input、net、sound等。
  • /sys/devices: 存放设备实例目录的地方,每个设备都有一个唯一的目录。
  • /sys/firmware: 存放固件文件的目录。
  • /sys/fs: 存放文件系统相关目录的地方,如cgroup、fuse等。
  • /sys/kernel: 存放内核相关信息的目录,如调度器、内存管理等。
  • /sys/module: 存放内核模块的目录。
  • /sys/power: 存放电源管理相关目录的地方,如休眠、唤醒等。
  • /sys/devices/virtual: 存放虚拟设备目录的地方,如虚拟终端、虚拟网卡等。

五、sysfs的使用

sysfs提供了一种可读可写的属性文件接口,可以通过该接口访问设备节点的属性。在/sys目录下,每个设备节点都有一个对应的目录,其中包含了一些属性文件,例如:

  • device:设备节点的名称。
  • driver:驱动程序的名称。
  • uevent:当设备节点的状态改变时会触发的事件,可以使用udev工具来处理这些事件。
  • power:设备的电源管理属性。

例如,要访问一个名为/sys/devices/pci0000:00/0000:00:01.0/usb3/3-1/3-1:1.0/net/eth0的设备节点,可以使用以下命令:

$ cat /sys/devices/pci0000:00/0000:00:01.0/usb3/3-1/3-1:1.0/net/eth0/operstate
up

这个命令可以显示eth0接口的状态(up表示接口已经启用)。

六、在Linux内核模块中使用sysfs

内核模块可以通过sysfs来暴露自己的参数和状态,以便于用户和应用程序可以访问和配置。在内核模块中,可以使用sysfs_create_file()函数创建一个属性文件,这个函数的参数包括:

  • 一个指向kobject结构的指针,这个结构描述了内核对象,例如设备或驱动程序。
  • 一个指向struct attribute结构的指针,这个结构描述了属性的名称和访问方式。
  • 一个指向读取属性的回调函数的指针。
  • 一个指向写入属性的回调函数的指针。

在内核模块中创建sysfs属性文件的一般步骤如下:

定义 kobject 结构体和sysfs_ops结构体

#include <linux/kobject.h>
#include <linux/sysfs.h>

static struct kobject *my_kobj;

static struct attribute my_attribute = {
    .name = "foo",
    .mode = 0644,
};

static struct attribute *my_attrs[] = {
    &my_attribute,
    NULL,
};

static ssize_t my_show(struct kobject *kobj, struct attribute *attr,
                       char *buf)
{
    // show函数的具体实现
}

static ssize_t my_store(struct kobject *kobj, struct attribute *attr,
                        const char *buf, size_t count)
{
    // store函数的具体实现
}

static struct sysfs_ops my_sysfs_ops = {
    .show = my_show,
    .store = my_store,
};

在上面的代码中,my_kobj是一个指向kobject结构体的指针,my_attribute是一个attribute结构体,用于表示foo属性文件.

my_attrs是一个指向attribute结构体指针的数组,用于表示内核对象的所有属性文件,my_showmy_store是用于读取和写入属性值的回调函数,my_sysfs_ops是一个sysfs_ops结构体,用于表示操作这些属性文件的回调函数集合。

初始化和注册 kobject

static int __init my_init(void)
{
    int ret;

    my_kobj = kobject_create_and_add("my_kobject", NULL);
    if (!my_kobj)
        return -ENOMEM;

    ret = sysfs_create_file(my_kobj, &my_attribute.attr);
    if (ret) {
        kobject_put(my_kobj);
        return ret;
    }

    my_kobj->ktype->sysfs_ops = &my_sysfs_ops;

    return 0;
}

static void __exit my_exit(void)
{
    kobject_put(my_kobj);
}

module_init(my_init);
module_exit(my_exit);

在上面的代码中,kobject_create_and_add函数用于创建并添加一个名为my_kobject的内核对象,sysfs_create_file函数用于将foo属性文件与my_kobject关联,my_kobj->ktype->sysfs_ops用于将my_sysfs_ops回调函数集合注册到my_kobj上。

七、结语

在Linux系统中,sysfs是一个非常重要的文件系统,它提供了一种用户空间与内核空间进行交互的方式,同时也是内核开发中一个非常有用的工具。

在本文中,我们学习了sysfs的基本概念和目录结构,以及如何使用sysfs来读取和修改内核对象的属性值,以及在内核模块中如何使用sysfs来创建属性文件并将其关联到内核对象中。

需要注意的是,sysfs是一种非常强大的工具,同时也是内核开发中非常重要的一部分。在使用sysfs时,一定要小心谨慎,遵循最佳实践,并确保正确处理错误情况。只有这样,才能充分利用sysfs的潜力,从而构建更加稳定和可靠的系统。

👇点击下方公众号卡片获取资料👇
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值