参考资料
TBD
后面持续更新。
misc是啥
相关数据结构
-misc_list链表
用来记录misc类下面注册过的设备。在misc设备注册与misc设备打开的过程中会要到。都是带锁访问。
-xx xxx
misc类的创建
上代码:
static int __init misc_init(void)
{
int err;
#ifdef CONFIG_PROC_FS
// 创建/proc/misc文件
proc_create("misc", 0, NULL, &misc_proc_fops);
#endif
//创建misc类,生成/sysfs/class/misc目录,misc类设备都放在这个目录下;
misc_class = class_create(THIS_MODULE, "misc");
err = PTR_ERR(misc_class);
if (IS_ERR(misc_class))
goto fail_remove;
err = -EIO;
// misc_fops
if (register_chrdev(MISC_MAJOR,"misc",&misc_fops))
goto fail_printk;
misc_class->devnode = misc_devnode;
return 0;
fail_printk:
printk("unable to get major %d for misc devices\n", MISC_MAJOR);
class_destroy(misc_class);
fail_remove:
remove_proc_entry("misc", NULL);
return err;
}
//将misc_init函数放到".initcall4.init"段,在内核启动过程中会自动调用。
subsys_initcall(misc_init);
misc设备的注册
misc_register(struct miscdevice * misc)
{
...
//判断misc_list链表中是否存在minor设备,已经注册过的直接返回。
list_for_each_entry(c, &misc_list, list) {
if (c->minor == misc->minor) {
mutex_unlock(&misc_mtx);
return -EBUSY;
}
}
...
//在misc类下创建misc设备
misc->this_device = device_create(misc_class, misc->parent, dev,
misc, "%s", misc->name);
...
//把刚刚创建的misc设备记录在misc_list中
list_add(&misc->list, &misc_list);
}
misc设备的读写
misc_init函数在初始化的时候,register_chrdev(MISC_MAJOR,“misc”,&misc_fops) 注册的是misc_fops文件操作,每次打开设备会执行misc_fops.misc_open。
在misc_open函数中会把 miscdevice 设备的 操作接口更新给 file对象。
static int misc_open(struct inode * inode, struct file * file)
{
...
list_for_each_entry(c, &misc_list, list) {
if (c->minor == minor) {
new_fops = fops_get(c->fops);
break;
}
}
...
old_fops = file->f_op;
file->f_op = new_fops;
if (file->f_op->open) {
file->private_data = c;
err=file->f_op->open(inode,file);
if (err) {
fops_put(file->f_op);
file->f_op = fops_get(old_fops);
}
}
...
}