Linux设备文件三大结构:inode,file,file_operations
struct inode
Linux中一切皆文件,当我们在Linux中创建一个文件时,就会在相应的文件系统创建一个inode与之对应,文件实体和文件的inode是一一对应的,创建好一个inode会存在存储器中,第一次open就会将inode在内存中有一个备份,同一个文件被多次打开并不会产生多个inode,当所有被打开的文件都被close之后,inode在内存中的实例才会被释放。既然如此,当我们使用mknod(或其他方法)创建一个设备文件时,也会在文件系统中创建一个inode,这个inode和其他的inode一样,用来存储关于这个文件的静态信息(不变的信息),包括这个设备文件对应的设备号,文件的路径以及对应的驱动对象etc。inode作为VFS四大对象之一,在驱动开发中很少需要自己进行填充,更多的是在open()方法中进行查看并根据需要填充我们的file结构。
对于不同的文件类型,inode被填充的成员内容也会有所不同,以创建字符设备为例,我们知道,cdev_add其实是把一个字符驱动对象和一个(一组)设备号联系到一起。而创建设备文件,其实是把设备文件和设备号联系到一起。至此,这三者就被绑定在一起了。这样,内核就有能力创建一个struct inode实例了。
struct inode { umode_t i_mode; unsigned short i_opflags; kuid_t i_uid; kgid_t i_gid; unsigned int i_flags; ... union { const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ void (*free_inode)(struct inode *); }; struct file_lock_context *i_flctx; struct address_space i_data; struct list_head i_devices; union { struct pipe_inode_info *i_pipe; struct cdev *i_cdev; char *i_link; unsigned i_dir_seq; }; ... void *i_private; /* fs or device private pointer */ }
特殊文件类型的union:pipe、cdev、link、dir_seq,i_cdev表示这个inode属于一个字符设备文件,创建字符设备文件的时候会把与之相关的设备号的驱动对象cdev拿来填充
i_fop:创建设备文件的时候,i_fop 填充的是def_chr_fops、def_blk_fops、pipefifo_fops之一,参见创建过程中调用的init_special_inode()
void init_special_inode(struct inode *inode, umode_t mode, dev_t rdev) { inode->i_mode = mode; if (S_ISCHR(mode)) { inode->i_fop = &def_chr_fops; inode->i_rdev = rdev; } else if (S_ISBLK(mode)) { inode->i_fop = &def_blk_fops; inode->i_rdev = rdev; } else if (S_ISFIFO(mode)) inode->i_fop = &pipefifo_fops; else if (S_ISSOCK(mode)) ; /* leave it no_open_fops */ else printk(KERN_DEBUG "init_special_inode: bogus i_mode (%o) for" " inode %s:%lu\n", mode, inode->i_sb->s_id, inode->i_ino); }
const struct file_operations def_chr_fops = { .open = chrdev_open, .llseek = noop_llseek, };
struct file
每一个进程维护一个打开文件描述符表。open()的过程其实就是根据传入的路径创建一个 file 并将其赋值到数组中,并返回其索引。
struct file { ... struct path f_path; struct inode *f_inode; /* cached value */ const struct file_operations *f_op; /* * Protects f_ep, f_flags. * Must not be taken from IRQ context. */ spinlock_t f_lock; enum rw_hint f_write_hint; atomic_long_t f_count; unsigned int f_flags; fmode_t f_mode; struct mutex f_pos_lock; loff_t f_pos; struct fown_struct f_owner; const struct cred *f_cred; struct file_ra_state f_ra; u64 f_version; #ifdef CONFIG_SECURITY void *f_security; #endif /* needed for tty driver, and maybe others */ void *private_data; ... }
f_path:存储的是open传入的路径,VFS就是根据这个路径逐层找到相应的inode
f_inode:存储的是找到的inode
f_op:存储的就是驱动提供的file_operations对象,这个对象应该在第一次open()的时候被填充,具体地,应用层的open通过层层搜索会调用inode.i_fops->open(),对于字符设备文件即chrdev_open()
相关文章
- linux驱动开发--字符设备:添加文件指针偏移的功能
- linux异常 - 弹出界面 eth0:设备eth0似乎不存在
- Linux中什么是块设备 及 lsblk命令的使用
- Linux下套接字详解(五)----基于fork多进程的TCP套接字(阻塞/同步/并发)
- Linux基础之查看linux发行版以及内核版本
- linux 打包为zip压缩包
- linux下通过acl配置灵活目录文件权限(可用于ftp,web服务器的用户权限控制)
- Linux shell脚本中单双引号的区别
- 【Linux 内核】调度器 ⑧ ( 进程优先级源码 includelinuxschedprio.h | 进程分类 | 实时进程 | 普通进程 | 进程优先级数值 | 0 ~ 99 实时进程 )
- Linux I2C设备驱动编写(三)-实例分析AM3359
- L55.linux命令每日一练 -- 第八章 Linux磁盘与文件系统管理命令 -- mkswap和swapon
- L44.linux命令每日一练 -- 第七章 Linux用户管理及用户信息查询命令 -- su和visudo
- L36.linux命令每日一练 -- 第五章 Linux信息显示与搜索文件命令 -- locate和updatedb
- L33.linux命令每日一练 -- 第五章 Linux信息显示与搜索文件命令 -- du和date
- 嵌入式linux开启无线热点模式(AP),联机设备通过 wifi 热点访问外网
- linux top命令及结果详解 top -p 查看Linux程序运行进程
- 第九章 linux-深入学习字符设备驱动编程①
- Linux设备驱动中的ioctl
- 《Linux Device Drivers》第十四章 Linux 设备型号
- linux达人养成计划学习笔记(四)—— 压缩命令
- linux驱动中如何自动生成设备文件节点?
- Linux设备文件自动生成