【linux kernel】linux内核伪文件系统—sysfs分析

linux内核伪文件系统—sysfs分析
一、sysfs简介

sysfs是一个伪文件系统。不代表真实的物理设备,在linux内核中,sysfs文件系统将长期存在于内存中。sysfs用于对具体的内核对象(例如物理设备)进行建模,并提供一种将设备和设备驱动程序关联起来的方法。使用

ls -l /sys

命令可以查看sysfs文件系统中导出了哪些内核对象。如下图片所示:

在这里插入图片描述

从上图可见,sysfs文件系统中导出了block、bus、class、dev、devices、firmware、fs、kernel、module、power内核对象(不同的内核配置,可能导出的内核对象有所差异)。

从内核源码来看。这里以bus内核对象为例,内核源码将在buses_init()函数中调用kset_create_and_add()内核函数创建bus对象集合并将其添加到sysfs文件系统中。

开发人员可以使用sysfs来确定有关正在运行的内核的有用信息,比如:内核在每个总线(bus)上发现了哪些设备,以及每个设备绑定了哪些驱动程序,都可以从sysfs文件系统获知。除此之外,sysfs还可以用于调试、优化设备以及其他的内核子系统。

当前块(block)子系统会使用sysfs来挂载根分区。如果禁用了sysfs,就必须在内核引导命令行上通过它的主号(major)和副号(minor)指定引导设备。例如,对于/dev/hda1设备来说,命令可以是root=03:01

对于嵌入式系统的设计人员,根据实际运用场景,可以禁用sysfs文件系统,以节省系统资源。

二、sysfs文件系统源码分析

首先,linux内核中关于sysfs文件系统的源码位于(/fs/sysfs)目录下。如下图所示(源码已被编译):
在这里插入图片描述

Makefile文件可知,编译过程中,将编译5个源文件:file.o dir.o symlink.o mount.o group.o

本部分内容就不分析sysfs文件系统的内部实现细节,主要分析以下两个问题:

(1)sysfs文件系统在linux内核中如何挂载的?

(2)linux内核如何将内核对象集添加到sysfs文件系统?

(2-1)sysfs文件系统在linux内核中如何挂载

start_kernel()函数中将调用vfs_caches_init(totalram_pages);函数进行虚拟文件系统的初始化,此函数中将调用mnt_init()函数,在mnt_init()函数中将调用sysfs_init()sysfs文件系统进行挂载。如下图片:
在这里插入图片描述

代码片段:

void __init mnt_init(void)
{
    //...
    
	kernfs_init();

	err = sysfs_init();
	if (err)
		printk(KERN_WARNING "%s: sysfs_init error: %d\n",
			__func__, err);

    //....
}

(/fs/sysfs/mount.c)

static struct file_system_type sysfs_fs_type = {
	.name		= "sysfs",
	.mount		= sysfs_mount,
	.kill_sb	= sysfs_kill_sb,
	.fs_flags	= FS_USERNS_VISIBLE | FS_USERNS_MOUNT,
};

int __init sysfs_init(void)
{
	int err;

	sysfs_root = kernfs_create_root(NULL, KERNFS_ROOT_EXTRA_OPEN_PERM_CHECK,
					NULL);
	if (IS_ERR(sysfs_root))
		return PTR_ERR(sysfs_root);

	sysfs_root_kn = sysfs_root->kn;

	err = register_filesystem(&sysfs_fs_type);
	if (err) {
		kernfs_destroy_root(sysfs_root);
		return err;
	}

	return 0;
}

上述代码第1-6行代码,定义了sysfs文件系统描述类型,指定了.name.mount.kill_sb.fs_flags

sysfs_init()函数中调用kernfs_create_root()kernfs是一个通用的内核虚拟文件系统,较为复杂本文暂不做过多分析)创建了kernfs_root。接着调用register_filesystem()向内核注册sysfs文件系统。

(2-2)linux内核如何将内核对象集添加到sysfs文件系统?

上文写道,linux内核中调用了kset_create_and_add()内核函数创建内核对象集,从而将内核对象集添加到sysfs文件系统下,本部分来看看该函数。

该函数有以下重要的函数调用关系:
在这里插入图片描述

由上图可见,kset_create_and_add()函数最后将调用到sysfs_create_dir_ns()这个函数。从而创建sysfs文件系统目录。代码片段如下所示:

(/fs/sysfs/dir.c)

int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
{
	struct kernfs_node *parent, *kn;

	BUG_ON(!kobj);

	if (kobj->parent)
		parent = kobj->parent->sd;
	else
		parent = sysfs_root_kn;

	if (!parent)
		return -ENOENT;

	kn = kernfs_create_dir_ns(parent, kobject_name(kobj),
				  S_IRWXU | S_IRUGO | S_IXUGO, kobj, ns);
	if (IS_ERR(kn)) {
		if (PTR_ERR(kn) == -EEXIST)
			sysfs_warn_dup(parent, kobject_name(kobj));
		return PTR_ERR(kn);
	}

	kobj->sd = kn;
	return 0;
}
三、总结

​ 本文从linux内核代码以及实际的系统运行效果为出发点,描述了sysfs文件系统的一些功能,并分析了linux内核如何初始化并挂载sysfs文件系统,以及inux内核如何将内核对象集添加到sysfs文件系统中的。


由于小生知识和精力有限,如若分享的文章存在有不妥的地方,请看官们多多批评,haha!

搜索关注【嵌入式小生】wx公众号获取更多精彩内容>>>>
请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iriczhao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值