版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l289123557/article/details/68614079
1. sysfs
1.1 sysfs文件系统注册
在系统启动时会注册sysfs文件系统
(fs/sysfs/mount.c)
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.2 API
在/sys目录下创建目录和各种文件有一系列API,下面总结介绍一些:
(include/linux/sysfs.h)
1.2.1 目录相关
int sysfs_create_dir_ns(struct kobject *kobj, const void *ns);
void sysfs_remove_dir(struct kobject *kobj);
int sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
const void *new_ns);
int sysfs_move_dir_ns(struct kobject *kobj,
struct kobject *new_parent_kobj,
const void *new_ns);
1.2.2 mount
int __must_check sysfs_create_mount_point(struct kobject *parent_kobj,
const char *name);
void sysfs_remove_mount_point(struct kobject *parent_kobj,
const char *name);
1.2.3 file
int __must_check sysfs_create_file_ns(struct kobject *kobj,
const struct attribute *attr,
const void *ns);
int __must_check sysfs_create_files(struct kobject *kobj,
const struct attribute **attr);
int __must_check sysfs_chmod_file(struct kobject *kobj,
const struct attribute *attr, umode_t mode);
void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr,
const void *ns);
bool sysfs_remove_file_self(struct kobject *kobj, const struct attribute *attr);
void sysfs_remove_files(struct kobject *kobj, const struct attribute **attr);
1.2.4 link
int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target,
const char *name);
int __must_check sysfs_create_link_nowarn(struct kobject *kobj,
struct kobject *target,
const char *name);
void sysfs_remove_link(struct kobject *kobj, const char *name);
int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *target,
const char *old_name, const char *new_name,
const void *new_ns);
void sysfs_delete_link(struct kobject *dir, struct kobject *targ,
const char *name);
2. kobject
sysfs下的设备都是通过分层组织归类的,要把这些关系组织起来,就是通过kobject,kobject在sysfs下的表现形式就是一个目录,而文件是由attribute来表示,由sysfs下的API函数来创建(如:sysfs_create_file_ns)
2.1 kobject
对于sysfs下的每个目录都用kobject来抽象
struct kobject {
const char *name;-------------------------名字
struct list_head entry;
struct kobject *parent;-----------------------父kobject指针
struct kset *kset;-------------------------所属kset
struct kobj_type *ktype;------------------------用于属性操作接口
struct kernfs_node *sd; /* sysfs directory entry */--kernfs接口
struct kref kref;--------------------------引用计数
#ifdef CONFIG_DEBUG_KOBJECT_RELEASE
struct delayed_work release;
#endif
unsigned int state_initialized:1;
unsigned int state_in_sysfs:1;
unsigned int state_add_uevent_sent:1;
unsigned int state_remove_uevent_sent:1;
unsigned int uevent_suppress:1;
};
kobject的创建
extern void kobject_init(struct kobject *kobj, struct kobj_type *ktype);
int kobject_add(struct kobject *kobj, struct kobject *parent,
const char *fmt, ...);
int kobject_init_and_add(struct kobject *kobj,
struct kobj_type *ktype, struct kobject *parent,
const char *fmt, ...);
kobject的删除
extern void kobject_del(struct kobject *kobj);
2.2 kset
kset就是一系列同类型kobject的集合,就像一个目录下会包含多个目录,上级目录一般是个kset,kobject和kset的关系如图所示:
struct kset {
struct list_head list;-------------------------链接所有kobject
spinlock_t list_lock;
struct kobject kobj;---------------------------嵌入的kobject
const struct kset_uevent_ops *uevent_ops;------kset操作函数
};
kset的创建及注册
extern void kset_init(struct kset *kset);
extern int __must_check kset_register(struct kset *kset);
kset的删除
extern void kset_unregister(struct kset *kset);
2.3 kobj_type
一些kobject下会有一些属性,在/sys下的表现形式就是文件,通过这些文件可以向用户提供一些操作接口
struct kobj_type {
void (*release)(struct kobject *kobj);------------释放kobject函数接口
const struct sysfs_ops *sysfs_ops;----------------属性操作函数实现接口
struct attribute **default_attrs;-----------------属性定义
const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj);
const void *(*namespace)(struct kobject *kobj);
};
struct attribute {
const char *name;----------------名字
umode_t mode;-----------------文件权限
#ifdef CONFIG_DEBUG_LOCK_ALLOC
bool ignore_lockdep:1;
struct lock_class_key *key;
struct lock_class_key skey;
#endif
};
3. 系统初始化sys创建的一些默认目录
(drivers/base/core.c)
int __init devices_init(void)
{
devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
if (!devices_kset)-------------------创建/sys/devices目录
return -ENOMEM;
dev_kobj = kobject_create_and_add("dev", NULL);
if (!dev_kobj)-----------------------创建/sys/dev目录
goto dev_kobj_err;
sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);
if (!sysfs_dev_block_kobj)-----------创建/sys/block目录
goto block_kobj_err;
sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);
if (!sysfs_dev_char_kobj)------------创建/sys/char目录
goto char_kobj_err;
return 0;
char_kobj_err:
kobject_put(sysfs_dev_block_kobj);
block_kobj_err:
kobject_put(dev_kobj);
dev_kobj_err:
kset_unregister(devices_kset);
return -ENOMEM;
}
(drivers/base/bus.c)
int __init buses_init(void)
{
bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
if (!bus_kset)------------------创建/sys/bus,初始化全局变量bus_kset
return -ENOMEM;
system_kset = kset_create_and_add("system", NULL, &devices_kset->kobj);
if (!system_kset)---------------创建/sys/system,初始化全局变量system_kset
return -ENOMEM;
return 0;
}