Linux字符设备驱动:cdev_add与device_create的差异及代码作用咨询
cdev_add与device_create:功能差异及代码中的作用详解
作为刚入门Linux字符设备驱动的新手,搞懂这两个函数的分工确实容易绕晕,我结合你贴的代码给你拆解清楚~
先快速过一遍你代码的流程:你先创建了一个设备类(在/sys/class下可见),接着初始化字符设备结构体并绑定驱动的操作回调(file_operations),然后调用cdev_add,最后用device_create生成用户可见的设备节点。
一、代码中两个函数分别实现的功能
1. cdev_add(&dummy_cdev, devt, 1)
这一步是把你的字符驱动正式注册到内核的字符设备框架中:
- 你之前用
cdev_init把自己写的dummy_fops(包含open、read、write等设备操作回调)和dummy_cdev结构体绑定在了一起,cdev_add就是把这个绑定好的结构体提交给内核。 - 它告诉内核:“以后只要有对
devt这个设备号的操作请求,就交给dummy_cdev对应的dummy_fops来处理”。 - 没有这一步,内核完全不知道你的驱动存在,哪怕用户空间有设备节点,操作时也会直接报错。
2. device_create(dummy_class, NULL, devt, NULL, "dummy_char")
这一步是给用户空间创建可访问的设备入口:
- 它基于你之前创建的
dummy_class,在sysfs中生成对应的设备属性信息,同时通知udev/mdev工具在/dev目录下创建名为dummy_char的设备文件。 - 没有这一步,你的驱动虽然已经在内核注册好了,但用户空间找不到可以操作的/dev节点,只能手动用
mknod命令创建设备节点,非常不友好。
二、两者的核心差异
- 工作层级不同:
cdev_add是纯内核态的操作,完全和用户空间无关,只负责让内核识别驱动逻辑。device_create是内核连接用户空间的桥梁,负责生成用户可见的设备节点。
- 职责边界清晰:
cdev_add管“驱动能不能被内核调度”,是驱动功能的后台注册。device_create管“用户能不能找到设备”,是驱动的前台入口创建。
- 依赖关系:
代码里先调用cdev_add再调用device_create是合理顺序——必须先让内核知道驱动存在,再创建用户入口,否则用户刚创建完节点就操作,内核还没准备好处理请求,会直接返回错误。
补充个小知识点:如果只调用cdev_add不调用device_create,你可以手动用mknod /dev/dummy_char c <major> <minor>创建设备节点来访问驱动;但如果只调用device_create没调用cdev_add,/dev/dummy_char虽然存在,但任何操作都会返回“没有这样的设备或地址”错误。
内容的提问来源于stack exchange,提问作者overlord
相关产品推荐
相关产品推荐

