Sysfs 文件系统:
" sysfs is a ram-based filesystem initially based on ramfs.
It provides a means to export kernel data stuctures,their attributes,and the linkages between them to userspace . "
让用户知道内核数据结构 ,属性,以及之间的关系.
Linux2.6 内核引入了 sysfs 文件系统,sysfs 被看成是与 proc 同类别的文件系统,
sysfs 把连接在系统上的 设备和总线 组织成分级的文件 ,使用户空间可以访问到 .
Sysfs 被加载在 /sys/ 目录下,
sys 下的子目录:
1,Block : 在系统中发现的每个块设备在该目录下对应一个子目录。
每个子目录中又包含一些属性文件,它们描述了这个块设备的各方面属性,比如:设备大小,
(loop 块设备是使用文件来模拟的.) 2,Bus :在内核中注册的每条总线 在该目录下对应一个子目录,
如:ide pci scsi usb pcmcia.
其中每个总线目录又包含两个子目录:devices 和drivers ,
devices 目录包含了在整个系统中发现的属于该总线类型的设备.
drivers 目录包含了注册到该总线的所有驱动.
3,Class : 将设备按照 功能 进行分类,如 /sys/class/net/ 目录下包含了所有网络接口.
4, Devices :包含系统所有等待设备.
5, Kernel :内核中的配置参数.
6, Module : 系统中所有模块信息.
Kobject :
Kobject 实现了基本的 面向对象管理机制 , 是构成 Linux2.6设备模型的核心结构 .
Kobject 与 sysfs 文件系统紧密相连,在内核中注册的每个 Kobject 对象对应 sysfs 文件系统 中的一个目录 .
Kobject 结构:
struct kobject { const char *name; struct list_head entry; struct kobject *parent; struct kset *kset; struct kobj_type *ktype; struct sysfs_dirent *sd; struct kref kref; unsigned intstate_initialized:1; unsigned intstate_in_sysfs:1; unsigned intstate_add_uevent_sent:1; unsigned intstate_remove_uevent_sent:1; unsigned intuevent_suppress:1; };
Kobject 操作:
void Kobject_init ( struct Kobject * kobj) 初始化 Kobject 结构; void Kobject_add ( struct Kobject * kobj) 将 Kobject 对象注册到 Linux 系统; int Kobject _init_and_add ( struct Kobject * kobj, struct kobj_type * ktype, struct Kobject * parent , const char * fmt , ...) 初始化并注册; void Kobject_del ( struct Kobject * kobj) 从 Linux 系统中删除 Kobject 对象. struct Kobject * Kobject_get ( struct Kobject * kobj) 将Kobject 对象引用计数加 1 ,同时返回该对象指针; void Kobject_put ( struct Kobject * kobj) 将 Kobject 对象应用计数减 1 ,如果引用计数将为 0, 则调用 release 方法释放 Kobject 对象;
struct kobj_type :
Kobject 的
ktype
成员是一个
指向 kobj_type
结构的
指针
,该结构中记录了 Kobject 对象的一些属性.
struct kobj_type { void (*release) ( struct kobject * kobj); struct sysfs_ops *sysfs_ops; struct attribute ** default_attrs; };
release:
用于释放 kobject 占用的资源,当 kobject 的引用计数为 0 时,被调用.
struct attribute :
struct attribute (属性) :对应于 kobject 的目录下的一个文件,Name 成员就是文件名.
struct attribute { char * name; struct module *owner; mode_t mode ; }
struct sysfs_ops :
struct sysfs_ops { ssize_t (*show) ( struct kobject *, struct attribute *, char *) ; ssize_t (*store) ( struct kobject *, struct attribute *, const char *, size_t ) ; };
show
:当用户
读
属性文件时,该函数被调用,该函数将属性值
存入 buffer
中返
回给用户态
.
store :当用户写 属性文件时,该函数被调用,用于存储用户传入的属性值 .
下面是实例代码 kobject.c 文件:
#include <linux/device.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/string.h> #include <linux/sysfs.h> #include <linux/stat.h> MODULE_AUTHOR("David Xie" ); MODULE_LICENSE("Dual BSD/GPL" ); void obj_test_release( struct kobject *kobject); ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr, char *buf); ssize_t kobj_test_store(struct kobject *kobject, struct attribute *attr, const char *buf, size_t count); struct attribute test_attr = { .name = "kobj_config" , .mode = S_IRWXUGO, }; static struct attribute *def_attrs[] = { &test_attr, NULL, }; struct sysfs_ops obj_test_sysops = { .show = kobj_test_show, .store = kobj_test_store, }; struct kobj_type ktype = { .release = obj_test_release, .sysfs_ops=&obj_test_sysops, .default_attrs=def_attrs, }; void obj_test_release( struct kobject *kobject) { printk("eric_test: release .\n" ); } ssize_t kobj_test_show(struct kobject *kobject, struct attribute *attr, char *buf) { printk("have show.\n" ); printk("attrname:%s.\n" , attr->name); sprintf(buf,"%s\n" ,attr->name); return strlen(attr->name)+2; } ssize_t kobj_test_store(struct kobject *kobject, struct attribute *attr, const char *buf, size_t count) { printk("havestore\n" ); printk("write: %s\n" ,buf); return count; } struct kobject kobj; static int kobj_test_init() { printk("kboject test init.\n" ); kobject_init_and_add(&kobj,&ktype,NULL,"kobject_test" ); return 0; } static int kobj_test_exit() { printk("kobject test exit.\n" ); kobject_del(&kobj); return 0; } module_init(kobj_test_init); module_exit(kobj_test_exit);
代码测试效果: