首先从mknod系统调用看起
看mknod命令调用的系统调用
执行的命令:mknod /dev/test_char c 128 11
可以使用工具看到核心调用如下
mknod("/dev/test_char", S_IFCHR|0666, makedev(128, 11)) = 0
mknod对应的内核函数为sys_mknod
sys_mknod
vfs_mknod error = dir->i_op->mknod(dir, dentry, mode, dev);
上图是sys_mknod的源码可以看到在mode是S_IFCHR的时候调用的是vfs_mknod。
可以看到 vfs_mknod只是i_op->inode的封装。dir是nd.dentry->d_inode也就是/dev这个目录对应的inode。如果/dev是ext3下的文件系统。
则对应上图的 ext3_mknod
从上图可以看出在 新分配的 init_special_inode(inode, inode->i_mode, rdev);
对于S_ISCHR的mode则会使用
inode->i_fop = &def_chr_fops
inode->i_rdev = rdev
可以看到def_chr_fops使用的是
接着看chrdev_open实现
从上图可以看到根据rdev号查找对应的kobj,然后再根据kobj找到对应的cdev,然后将 filp->f_op = fops_get(p->ops);(这里的p就是刚找到的cdev)。
然后看sys_open函数
可以看到sys_open会调用filp_open函数,进而调用dentry_open函数
可以看到 f->f_op = fops_get(inode->i_fop)等于f->f_op = def_chr_fops,则接下来会继续调用f->f_op->open函数则会调用到chrdev_open改变f->f_op为cdev->ops,则从此后完成驱动的操作函数与/dev/test_char文件的绑定。