创建设备文件的机制有以下下列几种:
- mknod命令:手动创建设备节点的命令
- devfs:可以用于创建设备节点,创建设备节点的逻辑在内核空间(内核2.4版本之前使用)
- udev:自动创建设备节点的机制,创建设备节点的逻辑在用户空间(从内核2.6版本一直使用至今)
- mdev:是一种轻量级的udev机制,用于一些嵌入式操作系统中
今天我们只研究udev自动创建设备节点udev的实现过程 ,具体过程如下图:
流程图:
udev是用户空间的一个应用程序,在内核空间中安装驱动时,驱动会向用户空间提供信息,向上提交目录名,在这个目录下提交设备信息,当提交信息时,后台运行的hutplug会监测 /sys/class/目录/信息 是否产生新的目录、新的信息,当产生新的信息时,hotplug会通知udev,udev会在/dev/下创建节点。
udev创建设备节点使用的API分析:
#include<linux/device.h> 1.向上提交目录信息 struct class * class_create(struct module *owner,const char *name ); 功能:申请一个设备类并初始化,向上提交目录信息 参数: owner:指向当前内核模块自身的一个模块指针,填写THIS_MODULE name:向上提交的目录名 返回值:成功返回申请的struct class对象空间首地址,失败返回错误码指针/*在内核空间最顶层会预留4K空间,当struct class函数调用失败后函数会返回一个指向这4K空间的指针bool __must_check IS_ERR(__force const void *ptr)功能:判断指针是否指向4K预留空间参数:要判断的指针返回值:如果指着指向4K预留空间返回逻辑真,否则返回逻辑假long __must_check PTR_ERR(__force const void *ptr)功能:通过错误码指针得到错误码ex:struct class_create *cls=struct class_create(THIS_MODULE,"mycdev");if(IS_ERR(cls)){printk("向上提交目录失败\n");return -PRT_ERR(cls); }*/2.销毁目录 void class_destroy(struct class *cls)功能:销毁目录信息 参数:cls:指向class对象的指针 返回值:无3.向上提交节点信息 struct device *device_create(struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *fmt, ...)功能:创建一个设备对象,向上提交设备节点信息 参数: cls:向上提交目录时的到的类对象指针 parent:当前申请的对象前一个节点的地址,不知道就填 NULL devt:设备号 主设备号<<20|次设备号/*MKDEV(主设备号,次设备号):根据主设备号和次设备号得到设备号MAJOR(dev):根据设备号获取主设备号MINOR(dev):根据设备号获取次设备号*/ dridata:申请的device对象的私有数据,填写NULL fmt:向上提交的设备节点名 ...:不定长参数 返回值:成功返回申请到的device对象首地址,失败返回错误码指针,指向4K预留空间4.销毁设备节点信息 void device_destroy(struct class *class, dev_t devt)功能:销毁设备节点信息 参数: class:向上提交目录时得到的类对象指针 devt:向上提交设备节点信息时提交的设备号 返回值:无
总结起来,udev通过与内核的协作,实现了在设备插入和移除时自动创建和管理相应的设备节点。这个过程主要包括内核设备驱动程序的检测、内核事件通知、udev守护进程的规则匹配、设备节点的创建和属性设置,最后通知用户空间相关应用程序。