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文件系统,以节省系统资源。
从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文件系统。
sysfs
文件系统?上文写道,linux内核中调用了kset_create_and_add()
内核函数创建内核对象集,从而将内核对象集添加到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
文件系统中的。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- bangwoyixia.com 版权所有 湘ICP备2023022004号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务