Linux中字符设备的注册过程是比较简单的。我们通常可以调用misc_register()函数来注册一个字符设备。Misc设备是一种字符设备,通过该设备可以将fops请求转发给注册的misc设备,从而实现字符设备的功能。用户调用该接口注册Misc字符设备时,可以动态分配设备Minor号,当获取Minor号之后调用class_simple_device_add()或者device_create()函数完成字符设备的创建。Misc字符设备注册函数如下所示:
int misc_register(struct miscdevice * misc)
{
struct miscdevice *c;
dev_t dev;
int err = 0;
INIT_LIST_HEAD(&misc->list);
mutex_lock(&misc_mtx); //获取misc设备信号量
list_for_each_entry(c, &misc_list, list) { //检查设备是否已经存在
if (c->minor == misc->minor) {
mutex_unlock(&misc_mtx);
return -EBUSY; //如果设备存在,直接返回
}
}
if (misc->minor == MISC_DYNAMIC_MINOR) { //动态分配分配minor号
int i = DYNAMIC_MINORS;
while (--i >= 0)
if ( (misc_minors[i>>3] & (1 << (i&7))) == 0)
break;
if (i<0) {
mutex_unlock(&misc_mtx);
return -EBUSY;
}
misc->minor = i;
}
if (misc->minor < DYNAMIC_MINORS)
misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
dev = MKDEV(MISC_MAJOR, misc->minor);
misc->this_device = device_create(misc_class, misc->parent, dev,
"%s", misc->name); //创建字符设备(Misc设备)
if (IS_ERR(misc->this_device)) {
err = PTR_ERR(misc->this_device);
goto out;
}
/*
* Add it to the front, so that later devices can "override"
* earlier defaults
*/
list_add(&misc->list, &misc_list); //将设备保存至misc设备链中,设备访问时需要操作该链表
out:
mutex_unlock(&misc_mtx);
return err;
}