class_create函数源码分析

简介: class_create函数源码分析

class_create函数源码分析


宏class_create()用于动态创建设备的逻辑类,并完成部分字段的初始化,然后将其添加进Linux内核系统中。此函数的执行效果就是在/sys/class/目录下创建一个新的文件夹,此文件夹的名字为此函数的第二个输入参数,但此文件夹是空的。宏class_create()在实现时,调用了函数__class_create()。

/**
 * class_create - create a struct class structure
 * @owner: pointer to the module that is to "own" this struct class
 * @name: pointer to a string for the name of this class.
 *
 * This is used to create a struct class pointer that can then be used
 * in calls to device_create().
 *
 * Returns &struct class pointer on success, or ERR_PTR() on error.
 *
 * Note, the pointer created here is to be destroyed when finished by
 * making a call to class_destroy().
 */
#define class_create(owner, name)   \
({            \
  static struct lock_class_key __key; \
  __class_create(owner, name, &__key);  \
})

owner:一个struct module结构体类型的指针,指向函数__class_create()即将创建的、“拥有”这个struct class的模块。一般赋值为THIS_MODULE,此结构体的详细定义见文件include/linux/module.h。

       name:char类型的指针,代表即将创建的struct class变量的名字,用于给struct class的name字段赋值。通俗地说,就是指向struct class名称的字符串的指针。

       __class_create()具体实现如下:

/**
 * __class_create - create a struct class structure
 * @owner: pointer to the module that is to "own" this struct class
 * @name: pointer to a string for the name of this class.
 * @key: the lock_class_key for this class; used by mutex lock debugging
 *
 * This is used to create a struct class pointer that can then be used
 * in calls to device_create().
 *
 * Returns &struct class pointer on success, or ERR_PTR() on error.
 *
 * Note, the pointer created here is to be destroyed when finished by
 * making a call to class_destroy().
 */
struct class *__class_create(struct module *owner, const char *name,
           struct lock_class_key *key)
{
  struct class *cls;
  int retval;
  cls = kzalloc(sizeof(*cls), GFP_KERNEL);
  if (!cls) {
    retval = -ENOMEM;
    goto error;
  }
  cls->name = name;
  cls->owner = owner;
  cls->class_release = class_create_release;
  retval = __class_register(cls, key);
  if (retval)
    goto error;
  return cls;
error:
  kfree(cls);
  return ERR_PTR(retval);
}
EXPORT_SYMBOL_GPL(__class_create);

分析源码可知__class_create()调用了__class_register()函数,它的具体实现如下:

int __class_register(struct class *cls, struct lock_class_key *key)
{
  struct subsys_private *cp;
  int error;
  pr_debug("device class '%s': registering\n", cls->name);
  cp = kzalloc(sizeof(*cp), GFP_KERNEL);
  if (!cp)
    return -ENOMEM;
  klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put);
  INIT_LIST_HEAD(&cp->interfaces);
  kset_init(&cp->glue_dirs);
  __mutex_init(&cp->mutex, "subsys mutex", key);
  error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name);
  if (error) {
    kfree(cp);
    return error;
  }
  /* set the default /sys/dev directory for devices of this class */
  if (!cls->dev_kobj)
    cls->dev_kobj = sysfs_dev_char_kobj;
#if defined(CONFIG_BLOCK)
  /* let the block class directory show up in the root of sysfs */
  if (!sysfs_deprecated || cls != &block_class)
    cp->subsys.kobj.kset = class_kset;
#else
  cp->subsys.kobj.kset = class_kset;
#endif
  cp->subsys.kobj.ktype = &class_ktype;
  cp->class = cls;
  cls->p = cp;
  error = kset_register(&cp->subsys);
  if (error) {
    kfree(cp);
    return error;
  }
  error = class_add_groups(class_get(cls), cls->class_groups);
  class_put(cls);
  return error;
}
EXPORT_SYMBOL_GPL(__class_register);

注意:

       1、class_create宏需要与函数class_destroy()配对使用,不能单独使用。当单独使用时,第一次不会出现错误,但当第二次插入模块时就会出现错误。

       2、class_create创建一个逻辑类后,还需在这个类下面创建设备,不然的话这个类没什么用。

相关文章
|
5月前
|
Java API 数据库
Java一分钟之-JPA注解:@Entity, @Table, @Id等
【6月更文挑战第14天】Java Persistence API (JPA) 是Java开发中的ORM框架,通过注解简化数据访问层。本文介绍了三个核心注解:`@Entity`标识实体类,`@Table`自定义表名,`@Id`定义主键。易错点包括忘记添加`@Entity`、未正确设置主键。建议使用`@GeneratedValue`和`@Column`细化主键策略和字段映射。正确理解和应用这些注解能提高开发效率和代码质量。
230 3
|
12天前
|
设计模式
在实际开发中,什么时候应该使用 `new` 关键字,什么时候应该使用 `Object.create()` 方法?
【10月更文挑战第29天】`new` 关键字适用于创建具有特定类型和初始化逻辑的对象实例,以及实现基于原型链的继承;而 `Object.create()` 方法则适用于基于现有对象创建相似对象、避免构造函数的副作用、创建具有特定原型链的对象等场景。在实际开发中,需要根据具体的需求和设计模式来选择合适的方法来创建对象,以实现更高效、更灵活的代码结构。
|
2月前
|
Java
java基础(4)public class 和class的区别及注意事项
本文讲解了Java中`public class`与`class`的区别和注意事项。一个Java源文件中只能有一个`public class`,并且`public class`的类名必须与文件名相同。此外,可以有多个非`public`类。每个类都可以包含一个`main`方法,作为程序的入口点。文章还强调了编译Java文件生成`.class`文件的过程,以及如何使用`java`命令运行编译后的类。
38 3
java基础(4)public class 和class的区别及注意事项
|
5月前
|
安全 Java 编译器
springboot @resource与private final声明式的有何区别??
【6月更文挑战第3天】在Spring Boot中,@Resource 和 private final 常用于依赖注入,但它们的用途和行为有一些重要的区别。
185 1
|
缓存 JavaScript 算法
v-if和v-show的区别及源码分析
v-if和v-show的区别及源码分析
135 1
|
缓存 安全 Java
ArrayList源码分析之add 方法
ArrayList源码分析之add 方法
132 0
class_destroy源码分析
class_destroy源码分析
|
Java Spring
FileSystemResource和ClassPathResource有何区别?
FileSystemResource和ClassPathResource有何区别?
FileSystemResource和ClassPathResource有何区别?
|
JavaScript 前端开发 程序员
Class-总结 class 的基本用法和两个注意点|学习笔记
快速学习 Class-总结 class 的基本用法和两个注意点
186 0
|
前端开发 JavaScript 开发者
介绍 class 创建的组件中 this.state |学习笔记
快速学习介绍 class 创建的组件中 this.state
139 0