Sysfs学习记录
主要参考文献:https://xuesong.blog.csdn.net/article/details/109522945
Sysfs(System File System)是一种虚拟文件系统,它提供了一种在Linux和Unix系统中管理设备和内核参数的机制。Sysfs基于内核,将底层硬件信息和内核参数暴露给用户空间应用程序
例如CPU温度、内存使用情况等。此外,Sysfs还允许用户空间程序动态更改内核参数,从而实现更高效的系统管理和调整。
Sysfs的基本概念:
节点(Node):Sysfs中的每个目录都表示一个节点,通常以斜杠(/)开头。例如,/sys/devices/pci0000:00/0000:00:00.0/resource_bus_width表示PCI总线宽度的节点。
属性(Attribute):每个节点都有一组属性,用于描述该节点所代表的对象或设备的相关信息。例如,/sys/devices/pci0000:00/0000:00:00.0/resource_bus_width具有ro(只读)属性,表示该属性只能由root用户读取。
文件(File):Sysfs中的每个属性都可以关联一个文件,用于存储相关的数据。例如,/sys/devices/pci0000:00/0000:00:00.0/resource_bus_width/value表示PCI总线宽度的实际值。
要访问Sysfs,您可以使用类似于ls、cat和grep等命令行工具。例如,要查看所有CPU核心的频率信息,您可以运行以下命令:
ls -l /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
请注意,Sysfs可能会因不同的Linux发行版而有所不同。在某些情况下,它可能被替换为其他类型的虚拟文件系统。
Sysfs tree
sysfs要素关系
下面主要介绍内核对象kobject和目录之间的关系;
对象属性内容也较多,且在用户层和设备树有一定关系,先不做介绍可单独开篇;
sysfs中kobject和kset的关系结构
单独的kobject和kset都略微看了下,不看大佬的文章,我是没出来如此详细的关系图;
kobject
kobject 结构体include/linux/kobject.h
包含了一些常用的成员变量,如 name, parent, siblings, ktype, kref 等。其中,name 成员变量表示对象的名称,parent 成员变量表示对象的父对象,siblings 成员变量表示同级的对象列表,ktype 成员变量表示对象的类型,kref 成员变量表示对象的引用计数。
struct kobject *kobject_create(void)
{
struct kobject *kobj;
kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
if (!kobj)
return NULL;
kobject_init(kobj, &dynamic_kobj_ktype);
return kobj;
}
struct kobject *kobject_create_and_add(const char *name, struct kobject *parent)
{
struct kobject *kobj;
int retval;
kobj = kobject_create();
if (!kobj)
return NULL;
retval = kobject_add(kobj, parent, "%s", name);
if (retval) {
printk(KERN_WARNING "%s: kobject_add error: %d\n",
__func__, retval);
kobject_put(kobj);
kobj = NULL;
}
return kobj;
}
使用kobject_create_and_add
来进行创建和添加目录,传参如果是NULL
则代表是sys主目录下,否则依次往下建立目录;device_attribute
是一个文件的属性value,后面可以在介绍,可以通过这个给他传值;
struct kobject *firmware_kobj;
EXPORT_SYMBOL_GPL(firmware_kobj);
firmware_kobj = kobject_create_and_add("firmware", NULL);
acpi_kobj = kobject_create_and_add("acpi", firmware_kobj);
hotplug_kobj = kobject_create_and_add("hotplug", acpi_kobj);
result = sysfs_create_file(acpi_kobj, &pm_profile_attr.attr);
root@ATP-YQYF-459:/sys# ls
block bus class dev devices firmware fs kernel module power
上述kobject_create_and_add
创建了/sys/firmware/acpi/hotplug
kobject_add_internal
将kobject添加到kernel。使用parent = kobject_get(kobj->parent);
申请内存增加引用计数。,error = create_dir(kobj);
创建目录;kobject_put,以内部接口kobject_release为参数,调用kref_put。kref模块会在引用计数为零时,调用kobject_release。kobject_put
释放内存kfree;
kset
Kset是一个特殊的kobject,因此其初始化、注册等操作也会调用kobject的相关接口,除此之外,会有它特有的部分。另外,和Kobject一样,kset的内存分配,可以由上层软件通过kmalloc自行分配,也可以由Kobject模块负责分配
edd_kset = kset_create_and_add("edd", NULL, firmware_kobj);