总结:自动创建设备节点udev的流程
1.如何创建节点
手动创建:mknod 地址 设备文件类型 主设备号 次设备号(0 - 255)
自动创建:devfs (创建节点的逻辑在内核 ---> 2.4版本以前使用)
udev (创建节点的逻辑在应用层)
mdev (轻量级的udev)
2.udev的流程
1> 硬件层接入,将硬件信息加载到内核层
2> 内核层向应用层提交目录(创建设备类:struct class)
和设备节点(创建设备对象:struct device)
3>同时发起hotplug event,应用层hotplug进程收到event,通知udev进程
4>udev进程创建/dev/设备文件,同时在/sys/class/下创建目录和文件(/sys/class/目录/文件)
3.相关API
1> struct class *class_create(struct module *owner, const char *name)
功能:向上提交目录,在内核创建一个struct class类型的空间并初始化
参数: owner:模块指针,填写THIS_MODULE(宏定义,指向当前模块自身的一个指针) name:向上提交的目录名
返回值:成功返回创建好的struct class类型的指针,失败返回错误码指针
2> void class_destroy(struct class *cls)
功能:销毁目录
参数: cls:class_create函数创建的空间首地址
返回值:无
3> struct device *device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...)
功能:向上提交设备节点信息,在内核生成一个struct device空间并赋值
参数: class:class_create函数创建的空间首地址
parent:父节点地址,不知道填NULL
devt:设备号
MKDEV(主设备号,次设备号):通过主设备号和次设备号得到设备号
MAJOR(dev):根据设备号得到主设备号
MINOR(dev):根据设备号得到次设备号
drvdata:传递到device回调函数中的参数,填写NULL即可
fmt: 向上提交的设备节点名 ...:可填可不填
返回值:成功返回创建成功的struct device空间指针,失败返回错误码指针
4>void device_destroy(struct class *class, dev_t devt)
功能:销毁设备节点信息
参数: class:class_create函数创建的空间首地址
devt:向上提交设备信息时提交的设备号
5> 错误码
在3-4G的内核区域,最顶层预留了4K的空间,class_create函数执行失败函数返回值对应的指针是指向这4K预留空间的。
bool IS_ERR(const void *ptr) //(unsigned long)(void *)(x) >= (unsigned long)-MAX_ER
功能:用于判断指针是不是指向内核顶层预留的4K空间
返回值:如果指针指向4K预留空间,则返回真,否则返回假
long __must_check PTR_ERR(__force const void *ptr)
功能:通过错误码指针得到一个错误码