驱动程序就是向下控制硬件,向上提供接口,这里的向上提供的接口最终对应到应用层有三种方式:设备文件,/proc,/sys,其中最常用的就是使用设备文件,而Linux设备中用的最多的就是字符设备,本文就以字符设备为例来分析创建并打开一个字符设备的文件内部机制。

struct inode

Linux中一切皆文件,当我们在Linux中创建一个文件时,就会在相应的文件系统创建一个inode与之对应,文件实体和文件的inode是一一对应的,创建好一个inode会存在存储器中,第一次open就会将inode在内存中有一个备份,同一个文件被多次打开并不会产生多个inode,当所有被打开的文件都被close之后,inode在内存中的实例才会被释放。既然如此,当我们使用mknod(或其他方法)创建一个设备文件时,也会在文件系统中创建一个inode,这个inode和其他的inode一样,用来存储关于这个文件的静态信息(不变的信息),包括这个设备文件对应的设备号,文件的路径以及对应的驱动对象etc。inode作为VFS四大对象之一,在驱动开发中很少需要自己进行填充,更多的是在open()方法中进行查看并根据需要填充我们的file结构。
对于不同的文件类型,inode被填充的成员内容也会有所不同,以创建字符设备为例,我们知道,add_chrdev_region其实是把一个驱动对象和一个(一组)设备号联系到一起。而创建设备文件,其实是把设备文件设备号联系到一起。至此,这三者就被绑定在一起了。这样,内核就有能力创建一个struct inode实例了,下面是4.8.5内核中的inode。这个inode是VFS的inode,是最具体文件系统的inode的进一步封装,也是驱动开发中关心的inode,针对具体的文件系统,还有struct ext2_inode_info 等结构。

//include/linux/fs.h
 596 /*
 597  * Keep mostly read-only and often accessed (especially for
 598  * the RCU path lookup and 'stat' data) fields at the beginning
 599  * of the 'struct inode'
 600  */
 601 struct inode { 602         umode_t                 i_mode; 603         unsigned short          i_opflags; 604         kuid_t                  i_uid; 605