Linux 内核文件系统与设备操作流程分析(11) inode->i_fop = &def_fifo_fops; // // 如果是 SOCKET,则使用 def_sock_fops 函数集 // else if (S_ISSOCK(mode)) inode->i_fop = &bad_sock_fops; // // 如果不是以上四种类型则忽略,并打印提示信息。 // else printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o)\n", mode);}以上四种类型设备驱动的函数集都大同小异,这里我们仅以“字符”设备的函数集为例,可以看到 file_operations 结构只设置了 open 方法,把它指向了chrdev_open() 函数。那么我们的在设备驱动里指定的 struct file->f_op 函数怎么被调用的?继续看 chrdev_open() 函数实现。const struct file_operations def_chr_fops = { .open = chrdev_open,};此函数主要完成的工作就是填充并调用用户给出的 struct file->f_op 结构中的函数集。它首先尝试得到正确的字符设备结构,判断如果注册了相应的函数集则调用。int chrdev_open(struct inode * inode, struct file * filp){ struct cdev *p; struct cdev *new = NULL; int ret = 0; spin_lock(&cdev_lock); // // 得到相应的字符设备结构 // p = inode->i_cdev; if (!p) { struct kobject *kobj; int idx; spin_unlock(&cdev_lock);