linux裝置驅動模型 - sys/kobject
阿新 • • 發佈:2018-11-03
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;
}