Linux之Kobject

includelinuxkobject.h

struct kobject {
  const char  *name;   //name
  struct list_head entry;  //链接到kset建立层次结构
  struct kobject  *parent; //指向父节点,面对对象的层次结构
  struct kset  *kset;   //指向所属的kset
  struct kobj_type *ktype;  //attribute type
  struct sysfs_dirent *sd;  //
  struct kref  kref;   //Reference count
  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;
};

includelinuxkref.h

struct kref {
  atomic_t refcount;
};

void kobject_init(struct kobject *kobj, struct kobj_type *ktype)
{

  ...

  kobject_init_internal(kobj);//进行主要成员变量初始化
  kobj->ktype = ktype;
  return;

  ...

}

EXPORT_SYMBOL(kobject_init);

static void kobject_init_internal(struct kobject *kobj)
{

  ...

  kref_init(&kobj->kref);//初始化reference count为1
  INIT_LIST_HEAD(&kobj->entry);//prev和next都指向自己
  kobj->state_in_sysfs = 0;
  kobj->state_add_uevent_sent = 0;
  kobj->state_remove_uevent_sent = 0;
  kobj->state_initialized = 1;
}

int kobject_add(struct kobject *kobj, struct kobject *parent, const char *fmt, ...)
{

  ...

  retval = kobject_add_varg(kobj, parent, fmt, args);//add操作

  ...

}
EXPORT_SYMBOL(kobject_add);

static int kobject_add_varg(struct kobject *kobj, struct kobject *parent, const char *fmt, va_list vargs)
{
  int retval;

  retval = kobject_set_name_vargs(kobj, fmt, vargs);//设置Kobject名字
  kobj->parent = parent;//设置Kobject的parent
  return kobject_add_internal(kobj);//sysfs中添加kobject信息
}

static int kobject_add_internal(struct kobject *kobj)
{

  ...

  if (!kobj->name || !kobj->name[0]) //如果名字为空则退出
  {
    return -EINVAL;
  }

  parent = kobject_get(kobj->parent);//如果parent为真则增加kobj->kref计数,也就是父节点的reference count

   if (kobj->kset)
   {
      if (!parent)
      parent = kobject_get(&kobj->kset->kobj);//如果kobj->parent父节点为NULL,那么就以kobj->kset->konj作为父节点,并增加reference count
     kobj_kset_join(kobj);//把kobj的entry成员添加到kobj->kset->list的尾部,now 层次就是/kobj->kset->list指向kobj->parent->指向kset->kobj
     kobj->parent = parent;
   }

  error = create_dir(kobj);//以kobj创建目录和attribute文件,其中会判断,如果parent为NULL,那么就于sysfs_root下创建
  if (error) //创建失败,减少相关的reference count
  {
    kobj_kset_leave(kobj);
    kobject_put(parent);
    kobj->parent = NULL;    

    dump_stack();
   }
  else
    kobj->state_in_sysfs = 1;//创建成功,则object已经于systfs中了

}

原文地址:https://www.cnblogs.com/pokerface/p/6547063.html