linux中class_create和class_register說明
本文介紹linux中class_create和class_register的相關使用方法
1 class結構體介紹
內核中定義了struct class結構體,顧名思義,一個struct class結構體類型變量對應一個類,內核同時提供了class_create(…)函數,可以用它來創建一個類,這個類存放於sysfs下面,一旦創建好了這個類,再調用device_create(…)函數來在/dev目錄下創建相應的設備節點。這樣,加載模塊的時候,用戶空間中的udev會自動響應device_create(…)函數,去/sysfs下尋找對應的類從而創建設備節點。
2 class相關API說明
如下表:

3 class_create()使用示例
示例一,通過class_create()、class_destroy()去注冊和注銷/sys/class/my_char_dev
代碼如下:
1 #include <linux/module.h> 2 #include <linux/init.h> 3 #include <linux/device.h> 4 5 struct class *mem_class; 6 7 static int __init class_create_destroy_init(void) 8 { 9 // class_create動態創建設備的邏輯類,並完成部分字段的初始化,然后將其添加到內核中。創建的邏輯類位於/sys/class/。 10 // 參數: 11 // owner, 擁有者。一般賦值為THIS_MODULE。 12 // name, 創建的邏輯類的名稱。 13 mem_class = class_create(THIS_MODULE, "my_char_dev"); 14 if (mem_class==NULL) 15 { 16 printk("<0> create class failed!\n"); 17 return -1; 18 } 19 20 return 0; 21 } 22 23 static void __exit class_create_destroy_exit(void) 24 { 25 if (mem_class != NULL) 26 { 27 class_destroy(mem_class); 28 mem_class = NULL; 29 } 30 31 } 32 33 module_init(class_create_destroy_init); 34 module_exit(class_create_destroy_exit); 35 36 MODULE_LICENSE("GPL");
4 class_register()使用示例
示例二,通過class_register()、class_unregister()去注冊和注銷/sys/class/my_char_dev
代碼如下:
1 #include <linux/module.h> 2 #include <linux/init.h> 3 #include <linux/device.h> 4 #include <linux/slab.h> 5 6 #define CLASS_NAME "my_char_dev" 7 struct class *mem_class; 8 9 static void class_create_release (struct class *cls) 10 { 11 printk("%s\n", __func__ ); 12 kfree(cls); 13 } 14 15 static int __init class_create_destroy_init(void) 16 { 17 printk("%s\n", __func__); 18 19 int ret; 20 21 // 申請class結構體內存 22 mem_class = kzalloc(sizeof(*mem_class), GFP_KERNEL); 23 if (mem_class == NULL) 24 { 25 printk("create mem class failed!\n"); 26 return -1; 27 } 28 printk("create mem class success\n"); 29 30 mem_class->name = CLASS_NAME; 31 mem_class->owner = THIS_MODULE; 32 // 注銷時class時的回調函數,在此回調函數中釋放之前所分配的class結構體內存 33 mem_class->class_release = class_create_release; 34 35 // 將class注冊到內核中,同時會在/sys/class/下創建class對應的節點 36 int retval = class_register(mem_class); 37 if (ret) 38 { 39 printk("class_register failed!\n"); 40 kfree(mem_class); 41 return -1; 42 } 43 printk("class_register success\n"); 44 45 46 return 0; 47 } 48 49 static void __exit class_create_destroy_exit(void) 50 { 51 printk("%s\n", __func__); 52 53 if (mem_class != NULL) 54 { 55 class_unregister(mem_class); 56 mem_class = NULL; 57 } 58 } 59 60 module_init(class_create_destroy_init); 61 module_exit(class_create_destroy_exit); 62 63 MODULE_LICENSE("GPL");
附錄一,class_create()和class_register()對比
實際上,示例一和示例二是等價的。具體的可以通過查看class_create()和class_register()、class_destroy()和class_unregister()的源碼去驗證。
class_register()的代碼如下:
1 // 將class注冊到/sys/class/中 2 #define class_register(class) \ 3 ({ \ 4 static struct lock_class_key __key; \ 5 __class_register(class, &__key); \ 6 })
class_register()是通過調用__class_register()來注冊到sysfs中的。
__class_register()的代碼如下:
1 int __class_register(struct class *cls, struct lock_class_key *key) 2 { 3 struct class_private *cp; 4 int error; 5 6 pr_debug("device class '%s': registering\n", cls->name); 7 8 cp = kzalloc(sizeof(*cp), GFP_KERNEL); 9 if (!cp) 10 return -ENOMEM; 11 klist_init(&cp->class_devices, klist_class_dev_get, klist_class_dev_put); 12 INIT_LIST_HEAD(&cp->class_interfaces); 13 kset_init(&cp->class_dirs); 14 __mutex_init(&cp->class_mutex, "struct class mutex", key); 15 error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name); 16 if (error) { 17 kfree(cp); 18 return error; 19 } 20 21 /* set the default /sys/dev directory for devices of this class */ 22 if (!cls->dev_kobj) 23 cls->dev_kobj = sysfs_dev_char_kobj; 24 25 #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK) 26 /* let the block class directory show up in the root of sysfs */ 27 if (cls != &block_class) 28 cp->class_subsys.kobj.kset = class_kset; 29 #else 30 cp->class_subsys.kobj.kset = class_kset; 31 #endif 32 cp->class_subsys.kobj.ktype = &class_ktype; 33 cp->class = cls; 34 cls->p = cp; 35 36 // 將class注冊到內核中 37 error = kset_register(&cp->class_subsys); 38 if (error) { 39 kfree(cp); 40 return error; 41 } 42 error = add_class_attrs(class_get(cls)); 43 class_put(cls); 44 return error; 45 }
class_unregister()的代碼如下:
1 void class_unregister(struct class *cls) 2 { 3 pr_debug("device class '%s': unregistering\n", cls->name); 4 remove_class_attrs(cls); 5 // 將class從內核中注銷 6 kset_unregister(&cls->p->class_subsys); 7 }
下面,我們查看class_create()、class_destroy()的相關代碼。
class_create()的代碼如下:
1 #define class_create(owner, name) \ 2 ({ \ 3 static struct lock_class_key __key; \ 4 __class_create(owner, name, &__key); \ 5 })
class_create()是通過調用__class_create()注冊到內核中的。
__class_create()的代碼如下:
1 struct class *__class_create(struct module *owner, const char *name, 2 struct lock_class_key *key) 3 { 4 struct class *cls; 5 int retval; 6 7 // 分配class結構體 8 cls = kzalloc(sizeof(*cls), GFP_KERNEL); 9 if (!cls) { 10 retval = -ENOMEM; 11 goto error; 12 } 13 14 cls->name = name; 15 cls->owner = owner; 16 // class對應的釋放函數,在class從內核中注銷時會執行該函數 17 cls->class_release = class_create_release; 18 19 // 通過調用__class_register()將class注冊到內核中 20 retval = __class_register(cls, key); 21 if (retval) 22 goto error; 23 24 return cls; 25 26 error: 27 kfree(cls); 28 return ERR_PTR(retval); 29 }
class_create_release的代碼如下:
1 static void class_create_release(struct class *cls) 2 { 3 pr_debug("%s called for %s\n", __func__, cls->name); 4 // 釋放class結構體 5 kfree(cls); 6 }
實際上,__class_create()是通過調用__class_register()注冊到sysfs中的!所以,本質上,class_create()和class_register()的作用是類似的。
class_destroy()的代碼如下:
1 void class_destroy(struct class *cls) 2 { 3 if ((cls == NULL) || (IS_ERR(cls))) 4 return; 5 // 調用class_unregister()將class從內核中注銷 6 class_unregister(cls); 7 }
實際上,class_destroy()是通過調用class_unregister()實現的。
