Linux设备驱动模型二 kobject

kobject


1.1 kobject数据结构

kobjectsysfs文件系统的基础数据结构,它定义在include/linux/kobjec.h

struct kobject {   
   /*名称*/
   const char     *name;
   /*与与所属的kset(list成员)组成链表*/
   struct list_head   entry;	
   /*父kobject;此成员未指定时,默认指向所属kset的kobject成员;在/sys文件系统中表示目录的上一层*/
   struct kobject     *parent;	
   /*指向所属的kset,可为NULL*/
   struct kset        *kset;
   /*提供操作kobject属性特征(attribute)的接口*/
   struct kobj_type   *ktype;		
   /*sys文件信息*/
   struct sysfs_dirent    *sd;
   /*kobject的引用计数*/
   struct kref        kref;		
   
   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;
};   


kset的定义如下:

struct kset {
	/*与子kobject的entry成员组成链表*/
	struct list_head list;
	/*自旋锁*/
	spinlock_t list_lock;
	/*kobject*/
	struct kobject kobj;
	const struct kset_uevent_ops *uevent_ops;
}; 


kobj_type的定义如下:

struct kobj_type {
	/*释放函数*/
	void (*release)(struct kobject *kobj);
	/*sys文件操作函数*/
	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);
}; 

sysfs_direct被定义在fs/sysfs/sysfs.h,它的定义如下:

struct sysfs_dirent {
	atomic_t		s_count;
	atomic_t		s_active;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
	struct lockdep_map	dep_map;
#endif
	/*上级目录*/
	struct sysfs_dirent	*s_parent;
	struct sysfs_dirent	*s_sibling;
	/*名称*/
	const char		*s_name;

	const void		*s_ns; /* namespace tag */
	union {
		struct sysfs_elem_dir		s_dir;
		struct sysfs_elem_symlink	s_symlink;
		struct sysfs_elem_attr		s_attr;
		struct sysfs_elem_bin_attr	s_bin_attr;
	};

	unsigned int		s_flags;
	unsigned short		s_mode;
	ino_t			s_ino;
	struct sysfs_inode_attrs *s_iattr;
}; 


1.2 Kobject创建流程


我们看一下kobject的初始化过程。

初始化kobject有两种方式,分别是用kobject_init_and_addkobject_create_and_add函数,他们的区别是:

1)kobject_init_and_add传入一个kobject指针和kobj_type指针,然后进行初始化

2)kobject_create_and_add创建一个kobject变量,并返回其指针,它不用传入kobj_type指针

1.2.1 kobject_init_and_add


下面看kobject_init_and_add函数的实现:

/**
 * kobject_init_and_add - initialize a kobject structure and add it to the kobject hierarchy
 * @kobj: pointer to the kobject to initialize
 * @ktype: pointer to the ktype for this kobject.
 * @parent: pointer to the parent of this kobject.
 * @fmt: the name of the kobject.
 *
 * This function combines the call to kobject_init() and
 * kobject_add().  The same type of error handling after a call to
 * kobject_add() and kobject lifetime rules are the same here.
 */
int kobject_init_and_add(struct kobject *kobj, struct kobj_type *ktype,
                         struct kobject *parent, const char *fmt, ...)
{
    va_list args;
    int retval;

    kobject_init(kobj, ktype);

    va_start(args, fmt);
    retval = kobject_add_varg(kobj, parent, fmt, args);
    va_end(args);

    return retval;
} 

它首先调用了kobject_init函数,再调用kobject_add_varg函数。先看kobject_init函数的实现:

/**
 * kobject_init - initialize a kobject structure
 * @kobj: pointer to the kobject to initialize
 * @ktype: pointer to the ktype for this kobject.
 *
 * This function will properly initialize a kobject such that it can then
 * be passed to the kobject_add() call.
 *
 * After this function is called, the kobject MUST be cleaned up by a call
 * to kobject_put(), not by a call to kfree directly to ensure that all of
 * the memory is cleaned up properly.
 */
void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
{
    char *err_str;

    if (!kobj) {
        err_str = "invalid kobject pointer!";
        goto error;
    }
    /*ktype不能为NULL*/
    if (!ktype) {
        err_str = "must have a ktype to be initialized properly!\n";
        goto error;
    }
    if (kobj->state_initialized) {
        /* do not error out as sometimes we can recover */
        printk(KERN_ERR "kobject (%p): tried to init an init
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值