sysfs文件系统分析

相关文章链接:sysfs系统的实际使用-请点击这里查看文章

sysfs实现的功能

  1. 为用户空间提供一个层级视图结构。
  2. 提供统一的引用计数。
  3. 分别用show和store来提供属性数据的导出导入。
  4. 可向用户空间发送信号。
    ps:实现的诀窍就是将kobject和文件目录(directory entries)联系起来。

相关的结构体

struct kobject {
	const char		*name;		//kobject 的名称
	struct list_head	entry;		//连接下一个kobject结构
	struct kobject		*parent;		//指向父kobject结构
	struct kset		*kset;		//指向kset集合
	struct kobj_type	*ktype;		//指向kobject的类型描述
	struct sysfs_dirent	*sd;			//对应sysfs的文件目录
	struct kref		kref;			//kobject引用计数
	unsigned int state_initialized:1;	//kobject初始化标志位
	unsigned int state_in_sysfs:1;	//是否加入sysfs中
	unsigned int state_add_uevent_sent:1;
	unsigned int state_remove_uevent_sent:1;
	unsigned int uevent_suppress:1;
};
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
};
struct sysfs_ops {
	ssize_t	(*show)(struct kobject *, struct attribute *,char *);	//读
	ssize_t	(*store)(struct kobject *,struct attribute *,const char *, size_t); //写
	const void *(*namespace)(struct kobject *, const struct attribute *);
};

结构体之间的关系

kobject是整个文件系统的核心、基础,它类似于c++中的基类的作用。其中通过*parent的指针来构建了整个文件系统的视图。而在实际的使用中将它嵌入到其它的字符设备、平台设备等的结构,这样就将他们关联起来了。这种技巧在linux很多地方都有使用,比如container_of()。
kset实际上就是很多类型相同的kobject的合集。
kobj_type 对应不同的类型。
下面这个图很好的展示了它们的关系:
在这里插入图片描述

源码分析

常用函数

kobject相关操作函数

#include <linux/kobject.h>
void kobject_init(struct kobject *kobj);
int kobject_add(struct kobject *kobj);
extern int kobject_register(struct kobject *kobj);
void kobject_del(struct kobject *kobj);
void kobject_unregister(struct kobject *kobj);

kset相关的操作函数

#include <linux/kobject.h>
void kset_init(struct kset *kset);
int kset_add(struct kset *kset);
int kset_register(struct kset *kset);
void kset_unregister(struct kset *kset);

文件相关的操作函数

#include <linux/sysfs.h>
int sysfs_create_file(struct kobject *kobj, struct attribute *attr);
int sysfs_remove_file(struct kobject *kobj, struct attribute *attr);
int sysfs_create_bin_file(struct kobject *kobj, struct bin_attribute *attr);
int sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);
int sysfs_create_link(struct kobject *kobj, struct kobject *target, char
*name);
void sysfs_remove_link(struct kobject *kobj, char *name);

文件系统

目录结构

示例代码

#include <linux/device.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sysfs.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/stat.h>
void sysfs_test_release(struct kobject *kobj);
ssize_t	sysfs_test_show(struct kobject *, struct attribute *,char *);
ssize_t	sysfs_test_store(struct kobject *,struct attribute *,const char *, size_t);

struct attribute sysfs_test_attrs = {
	.name = "sysfs_test_attrs",
	.mode = S_IRWXUGO,
};
static struct attribute *def_attrs [] = {
	&sysfs_test_attrs,
	NULL,
};
struct sysfs_ops sysfs_test_ops = {
	.show = sysfs_test_show,			//read func
	.store = sysfs_test_store,			//write func
};
struct kobj_type ktype = {
	.release = sysfs_test_release,
	.sysfs_ops = &sysfs_test_ops,
	.default_attrs = def_attrs,
};
void sysfs_test_release(struct kobject *kobj)
{
	printk(KERN_WARNING"sysfs release test!\n");
}

/*when cat sysfs_test,show the attribute name*/
ssize_t	sysfs_test_show(struct kobject *kobj, struct attribute *attr,char *buf)
{
	printk(KERN_WARNING"call sysfs_test_show()\n");
	printk(KERN_WARNING"attrname:%s\n",attr->name);
	sprintf(buf,"%s\n",attr->name);
	return strlen(attr->name)+2;
}
/*when echo xxx > sysfs_test,show it*/
ssize_t	sysfs_test_store(struct kobject *kobj,struct attribute *attr,const char *buf, size_t count)
{
	printk(KERN_WARNING"call sysfs_test_store()\n");
	printk("count:%d,write:%s",count,buf);
	return count;
}

struct kobject kobj;		/*the kobject to be added*/

static int sysfs_test_init(void)
{
	int ret = 0;
	printk(KERN_WARNING"init the kobj in sysfs_test_init()\n");
/*init the kobj and add to kernel*/
	ret = kobject_init_and_add(&kobj,&ktype,NULL,"sysfs_test");		
	if (ret !=0) {
		printk("init kobj fail!\n");
		return ret;
	}
	return ret;
}

void sysfs_test_exit(void)
{
	printk(KERN_WARNING"sysfs test exit\n");
	kobject_del(&kobj);
}

MODULE_LICENSE("GPL");

module_init(sysfs_test_init);
module_exit(sysfs_test_exit);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值