用户态经过mknod创建文件,VFS负责把它索引到对应的inode上,让它和特定驱动关联。用户态调用open的时候,VFS再建立一个filep,并一块儿传递给那个驱动(register_chrdev的那个驱动),那个驱动自己有全部调用的回调,也能够给filp创建另外一套回调,无所谓,以后其余调用就直接能够指向设备自己了。node
这个应该回答原题的问题了。linux
而后回答动态模块的问题:数组
内核的动态模块原理和so的原理彻底同样,加载的时候同时展开代码段和数据段,但实施上有所不一样,so是lazy加载,没有用到的时候不会真正加载到内存中,但内核是真正加载。函数
ko中的全局变量,和非ko的全局变量同样,在模块加载后就一直在系统中。spa
不存在“重要模块”,模块是否加载,都是init程序的配置引发的,若是init初始化树中没有加载动态模块,就不会有任何动态模块加载到系统中。debug
一般动态模块不会“扫描”设备,动态模块只会“驱动”设备。好比你有一个平台设备的ko,你加载进去了,init_module中注册到platform_bus子系统中,platform_bus子系统会在注册的时候用match函数给你match一次全部当初有人报过给它的全部device,若是device和你的注册match,就会产生probe(),但你的驱动无权主动去扫描硬件的。反过来,若是是你的驱动先注册,真正的设备后插入(好比USB key),这个事情会同样发生。最终仍是match,而后probe。指针
mknod建立的文件是“设备文件”,区别与“普通文件”。
1: 设备驱动创建了这个设备node,这个Node 是设备文件,mknod时 程序使用设备的一个“接口”,经过此“接口”你能够访问到它指向的具体设备。若是你没有moknod ,在linux的“一切皆文件”的思想下,你怎么才能访问使用你的设备呢? 因此,“为设备创建一个文件吧”
2:当程序调用 open打开这 /dev/demon 的“文件时”, 此时的open仅仅是在VFS(虚拟文件系统)层面的open, VFS会在内存中建立一个 file_struct的结构,并返回一个fd, 其实fd 是和这个file_struct相关联的:
好比在进程的files_struct结构中,有fd数组和fd_array数据,fd存放文件描述符,fd_array存放进程打开的 file_struct, 其中每一个fd 指向fd_array中的一个元素。
3:fd_array中的存放的 是file_struct,每一个file_struct结构中都 有一个类型为file_operations毕结构的指针f_op,f_op指向了一组 能够对文件进行的操做的函数(好比read)。当真正对文件进行操做时(好比read),f_op指向的操做函数(read)会调用 “针对该文件所属的类型"的具体的真正的函数来执行操做。(好比:ext3_read() /MS_dos_read()).orm
因此对demon进行操做时,fd 和file_struct 最后仍是 指向 了你所 建立的 demon表明的设备。索引
在一切皆文件的思路下,设备文件/dev/demon 能够理解为“你的设备在VSF中的一个符号连接(VFS的inode,设备文件没有相应的磁盘inode(我在rhel6.5 x86_64:2.6.32-431环境下debugfs 看不到/dev下面文件的索引节点号),而普通的文件在磁盘是有inode的)”,当Open时,VSF为该inode(/dev/demon) 建立对应的 VSF的file_struct,以及fd。接口
fd和 file_struct 只是在你open设备时,在内存中建立, 能够把fd/file_struct 理解成 “你的设备在内存中的映射”。
inode 节点——> 文件在内核态中的fs中的描述结构,和具体文件系统类型无关,不属于哪个进程,在内核的生命周期中一直存在于内存中,表明文件的实体。。。 file ——> 文件在进程中的描述符,随着进程死亡而被释放。。 fd ——> 为了封装file的复杂性,提供给用户在进程中索引file的一个索引号,fd只是打开的file的一个索引,进程真正操做的文件结构是file。。。。。 桥接模式——> 也叫handle/body模式,Linux在file与inode直接模仿了桥接模式,只有open以后,file才与具体的inode桥接起来,互相通讯,一旦close,或者进程死亡,file能够消失,inode却随内核继续存在。经过桥接的隔离,file与inode能够分开进行各自的抽象和衍生,inode的组成元素有cdev, block_dev 等,于是向下能够管理操做各类字符设备,块设备。。。 mknod——>本质上是在/dev目录下建立一个inode节点,/dev目录通常有一个devtmpfs或者udevfs挂在在上面,也就是说mknod本质上就是建立/dev目录下的inode节点,建立过程当中,传入的设备号,使得inode节点能在Linux内核中相关的注册链表里够找到对应的cdev或者block_dev结构体桥接起来。。。 再回到桥接模式——> file——>inode ——> cdev/block_device 中间能够当作两个桥接,open使得file与inode桥接起来,mknod使得inode和cdev/block_device桥接起来,每一个部分均可以独自抽象衍生,和其它部分无关,只要调用的时候桥接起来就行。。。