1、Sysfs文件系統
"sysfsis a ram-based filesystem initially based on ramfs. It provides ameans to export kernel data structures, their attributes, and thelinkages between them to userspace.”
Linux2.6內核引入了sysfs文件系統。sysfs被看成是與proc同類別的文件系統。sysfs把連接在系統上的設備和總線組織成分級的文件,使其從用戶空間可以訪問到。
Sysfs被加載在 /sys/目錄下,它的子目錄包括:
1)Block:在系統中發現的每個塊設備在該目錄下對應一個子目錄。每個子目錄中
又包含一些屬性文件,它們描述了這個塊設備的各方面屬性,如:設備大小。(loop塊設備是使用文件來模擬的)
2)Bus:在內核中注冊的每條總線在該目錄下對應一個子目錄,如: ide pci scsi usbpcmcia 其中每個總線目錄內又包含兩個子目錄:devices和drivers ,devices目錄包含了在整個系統中發現的屬於該總線類型的設備,drivers目錄包含了注冊到該總線的所有驅動。
3)Class:將設備按照功能進行的分類,如/sys/class/net目錄下包含了所有網絡接口。
4)Devices:包含系統所有的設備。
5)Kernel:內核中的配置參數
6)Module:系統中所有模塊的信息
7)Firmware:系統中的固件
8)Fs:描述系統中的文件系統
9)Power:系統中電源選項
2、K object
實現了基本的面向對象管理機制,是構成Linux2.6設備模型的核心結構。它與sysfs文件系統緊密相連,在內核中注冊的每個kobject對象對應sysfs文件系統中的一個目錄。類似於C++中的基類,Kobject常被嵌入於其他類型(即:容器)中。如bus,devices,drivers都是典型的容器。這些容器通過kobject連接起來,形成了一個樹狀結構。
structk object {
constchar
*name;
structlist_head
entry;
structkobject
*parent;//指向父對象
structkset
*kset;
structkobj_type
*ktype;
structsysfs_dirent *sd;
structkref
kref;//對象引用計數
unsignedint state_initialized:1;
unsignedint state_in_sysfs:1;
unsignedint state_add_uevent_sent:1;
unsignedint state_remove_uevent_sent:1;
};
3、Kobject操作
1)voidkobject_init(struct kobject * kobj)初始化kobject結構
2)intkobject_add(struct kobject * kobj)將kobject對象注冊到Linux系統
3)intkobject_init_and_add(struct kobject *kobj, struct kobj_type*ktype,struct kobject *parent, const char *fmt, ...)初始化kobject,並將其注冊到linux系統
4)voidkobject_del(struct kobject * kobj)從Linux系統中刪除kobject對象
5)structkobject *kobject_get(struct kobject*kobj)將kobject對象的引用計數加1,同時返回該對象指針。
6)voidkobject_put(struct kobject *kobj)將kobject對象的引用計數減1,如果引用計數降為0,則調用release方法釋放該kobject對象。
4、 Struct kobj_type
Kobject的ktype成員是一個指向kobj_type結構的指針, 該結構中記錄了kobject對象的一些屬性。
structkobj_type {
void(*release)(struct kobject *kobj);
structsysfs_ops *sysfs_ops;
structattribute **default_attrs;
};
release:用於釋放kobject占用的資源,當kobject的引用計數為0時被調用。
5、Struct attribute
structattribute {
char *name; /*屬性文件名*/
structmodule * owner;
mode_tmode; /*屬性的保護位*/
};
struct attribute (屬性):對應於kobject的目錄下的一個文件,Name成員就是文件名。
6、Struct sysfs_ops
structsysfs_ops
{
ssize_t(*show)(struct kobject *, struct attribute *,char *);
ssize_t(*store)(struct kobject *,struct attribute *,const char *,
size_t);
};
1)Show:當用戶讀屬性文件時,該函數被調用,該函數將屬性值存入buffer中返回給用戶態;
2)Store:當用戶寫屬性文件時,該函數被調用,用於存儲用戶傳入的屬性值。
7、 kobject實例分析
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");
/*聲明release、show、store函數*/
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);
/*對應於kobject的目錄下的一個文件,Name成員就是文件名*/
struct attribute test_attr = {
.name = "kobj_config",
.mode = S_IRWXUGO,
};
static struct attribute *def_attrs[] = {
&test_attr,
NULL,
};
/kobject對象的操作
struct sysfs_ops obj_test_sysops =
{
.show = kobj_test_show,
.store = kobj_test_store,
};
/*定義kobject對象的一些屬性及對應的操作*/
struct kobj_type ktype =
{
.release = obj_test_release,
.sysfs_ops=&obj_test_sysops,
.default_attrs=def_attrs,
};
/*release方法釋放該kobject對象*/
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;//聲明kobject對象
static int kobj_test_init(void)
{
printk("kboject test init.\n");
kobject_init_and_add(&kobj,&ktype,NULL,"kobject_test");//初始化kobject對象kobj,並將其注冊到linux系統
return 0;
}
static void kobj_test_exit(void)
{
printk("kobject test exit.\n");
kobject_del(&kobj);
}
module_init(kobj_test_init);
module_exit(kobj_test_exit);