操作系统将虚拟内存分为内核空间和用户空间。内核空间严格保留用于运行内核、内核扩展和大多数设备驱动程序。相比之下,用户空间是所有用户模式应用程序工作的内存区域,必要时可以换出该内存。用户空间和内核空间之间的通信有多种方式,sysfs就是其中的一种。
sysfs 和proc一样是虚拟文件系统。Sysfs 中的文件包含有关设备和驱动程序的信息。Sysfs 中的某些文件甚至是可写的,用于配置和控制连接到系统的设备。Sysfs 始终挂载在 /sys 上。
Sysfs 中的目录包含设备的层次结构,因为它们连接到计算机。
Sysfs 是将系统信息从内核空间导出到特定设备的用户空间的常用方法。sysfs 与内核的设备驱动程序模型相关联。procfs 用于导出特定进程的信息,debugfs 用于导出开发人员的调试信息。
在了解 sysfs 之前,应该先了解Kernel Objects。
Sysfs 的核心内容是kobject.Kobject是连接sysfs和内核的桥梁,主要由定义在< linux/kobejct.h >的struct kobject来实现。struct kobject 表示内核对象,可能是设备等,例如在sysfs文件系统中显示为目录的内容。
kobject通常是嵌入在其它数据结构中的。
kobject的定义
#define KOBJ_NAME_LEN 20 struct kobject { char *k_name; char name[KOBJ_NAME_LEN]; //kobject的名字 struct kref kref; //提供引入计数 struct list_head entry; struct kobject *parent; //kobject的父节点,类似上一级目录一样 struct kset *kset; //一组kobjects,他们都嵌入在相同类型的结构中 struct kobj_type *ktype; //与kobject关联的类型 struct dentry *dentry; };
kobject是将大部分设备模型及其 sysfs 接口结合在一起的粘合剂。被用于/sys目录下创建kobject的目录。
创建和使用 sysfs 有几个步骤。
可以使用**kobject_create_and_add()**函数创建目录
struct kobject * kobject_create_and_add ( const char * name, struct kobject * parent); name:要创建kobject的名字 parent:需要创建所在的目录,加入传入NULL则在/sys/目录下创建目录 这个函数将动态地创建一个kobject对象然后注册到sysfs。如果kobject不能被创建,函数将返回NULL。
使用上面的接口可以在/sys目录下创建目录,接下来还需要创建sysfs文件,用于实现用户空间和内核空间的交互。我们可以使用sysfs属性创建sysfs文件。
属性在 sysfs 中表示为常规文件,每个文件一个值。有大量的辅助函数可用于创建 kobject 属性。它们都可以在头文件 sysfs.h 中找到。
kobj_attribute的定义
struct kobj_attribute { struct attribute attr; ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, char *buf); ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count); }; attr:表示要创建的文件的属性 show:指向在 sysfs 中读取文件时将调用的函数的指针 store:指向将在文件写入 sysfs 时调用的函数的指针 可以使用宏定义__ATTR创建属性 __ATTR(name, permission, show_ptr, store_ptr);
然后需要编写 show 和 store 函数
ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, char *buf); ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count);
每当我们向 sysfs 属性写入内容时,都会调用 Store 函数。
每当我们读取 sysfs 属性时,就会调用 Show 函数。
创建单个sysfs文件属性的接口函数
int sysfs_create_file ( struct kobject * kobj, const struct attribute * attr); kobj:创建对象的指针 attr:属性描述符
创建一组属性的接口
int sysfs_create_group ( struct kobject *kobj, const struct attribute_group *grp);
删除sysfs的接口
void sysfs_remove_file ( struct kobject * kobj, const struct attribute * attr);
欢迎访问我的博客