Chinaunix首页 | 论坛 | 博客
  • 博客访问: 252148
  • 博文数量: 101
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 95
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-12 12:35
文章分类

全部博文(101)

文章存档

2016年(5)

2015年(16)

2014年(37)

2013年(32)

2012年(8)

2011年(3)

我的朋友

分类: LINUX

2013-12-03 17:39:14

------------------------------------------------
#个人浅见,如有问题敬请谅解!
#kernel version: 2.6.26
#Author: andy wang
-------------------------------------------------
    相对于前面分析的总线,设备,驱动模型来说 ,linux class模型就相对比较简单了.我们这里先分析class的注册过程, 然后举一个利用class动态创建字符设备的实例.
linux /sys目录下有一个class目录,在这个目录下存放着所有注册在内核中的class设备.
 
class初始化
还是先来看看/sys/class目录是如何建立起来的:
382 int __init classes_init(void)
383 {
384         class_kset = kset_create_and_add("class", NULL, NULL);
385         if (!class_kset)
386                 return -ENOMEM;
387         return 0;
388 }
注册一个class_ket ,class这个目录在/sys下就创建起来了~~~~~~.
 
class创建并注册
老规矩先还是理理流程:
class_create()->class_register()->kset_register()
从这里的流程也可以看出class的注册是很简单的,它其实就是注册了一个ket
跟踪一下class_register()的代码:
137 int class_register(struct class *cls)
138 {
139         int error;
140
141         pr_debug("device class '%s': registering\n", cls->name);
142
143         INIT_LIST_HEAD(&cls->devices);
144         INIT_LIST_HEAD(&cls->interfaces);
145         kset_init(&cls->class_dirs);
146         init_MUTEX(&cls->sem);
147         error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name);
148         if (error)
149                 return error;
150
151 #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK)
152         /* let the block class directory show up in the root of sysfs */
153         if (cls != &block_class)
154                 cls->subsys.kobj.kset = class_kset;
155 #else
156         cls->subsys.kobj.kset = class_kset;
157 #endif
158         cls->subsys.kobj.ktype = &class_ktype;
159
160         error = kset_register(&cls->subsys);
161         if (!error) {
162                 error = add_class_attrs(class_get(cls));
163                 class_put(cls);
164         }
165         return error;
166 }
151-158, 定义cls->subsys.kobj ketktype, cls->subsys.kobj.kset = class_kset;  cls->subsys.kobj.ktype = &class_ktype; class_kset是初始化class创建的, class_ktype定义了class属性文件的操作方法.
160,注册一个kset ,会在/clsaa目录下创建相应的目录 .因为cls->subsys.kobj.kset = class_kset .
 
创建class属性文件
那么class层的属性文件是如何创建的呢?看看这个函数就很清楚了:
77 int class_create_file(struct class *cls, const struct class_attribute *attr)
 78 {
 79         int error;
 80         if (cls)
 81                 error = sysfs_create_file(&cls->subsys.kobj, &attr->attr);
 82         else
 83                 error = -EINVAL;
 84         return error;
 85 }
sysfs_create_file() 这个函数就不多解释了, 以前文章已经分析过了.
 
读写class属性文件
还是老办法 ,要找到读写class属性文件的方法,首先要找到该文件父目录kobj关联的ktype , 从上面注册class的代码中可以看出, cls->subsys.kobj.ktype = &class_ktype; 每个kobj都指定了class_ktype .好了,找到了ktype我们就可以看它读写文件的实现了.
static struct kobj_type class_ktype = {
  .sysfs_ops        = &class_sysfs_ops,
  .release     = class_release,
};
 static struct sysfs_ops class_sysfs_ops = {
  .show       = class_attr_show,
  .store        = class_attr_store,
};
 
static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr,
                          char *buf)
{
  struct class_attribute *class_attr = to_class_attr(attr);
  struct class *dc = to_class(kobj);
  ssize_t ret = -EIO;
 
  if (class_attr->show)
         ret = class_attr->show(dc, buf);
  return ret;
}
class文件读方法来分析, 首先是找到class_attr,然后调用它定义的show()方法.
 
阅读(389) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~