字符设备(二)之主要数据结构
2013-01-29 10:50
344 查看
一.linux文件系统和字符设备驱动
应用程序和VFS之间的接口是系统调用,而VFS和磁盘文件系以及普通设备之间接口是file_operation结构体成员函数,这个结构包含打开,关闭,读,写等各种对文件的操作
字符设备上层不涉及到磁盘,所以字符设备的file_operation成员函数直接由设备驱动提供。file_operation是字符设备的操作核心。
1.file结构体
文件结构体代表一个文件(若是设备,则为设备文件),系统中每个打开的文件在内核中都有个一个struct file,由内核在打开文件的时候创建,并传递给在文件上进行
操作的任何函数,在文件的所有实例都关闭后,内核释放这个数据结构。
驱动程序中常用如下类似代码检测用户打开文件的读写方式
VFS inode包含文件的各种信息,eg:大小,权限等,是linux管理文件系统的最小单位,也是文件系统连接任何子目录,文件的桥梁
应用程序和VFS之间的接口是系统调用,而VFS和磁盘文件系以及普通设备之间接口是file_operation结构体成员函数,这个结构包含打开,关闭,读,写等各种对文件的操作
字符设备上层不涉及到磁盘,所以字符设备的file_operation成员函数直接由设备驱动提供。file_operation是字符设备的操作核心。
1.file结构体
文件结构体代表一个文件(若是设备,则为设备文件),系统中每个打开的文件在内核中都有个一个struct file,由内核在打开文件的时候创建,并传递给在文件上进行
操作的任何函数,在文件的所有实例都关闭后,内核释放这个数据结构。
struct file { /* * fu_list becomes invalid after file_free is called and queued via * fu_rcuhead for RCU freeing */ union {//共用体不同时刻占用同一段内存 struct list_head fu_list; struct rcu_head fu_rcuhead;//2.6新加入的锁机制 } f_u; struct path f_path; #define f_dentry f_path.dentry//目录入口 #define f_vfsmnt f_path.mnt const struct file_operations *f_op;//和文件关联的操作 spinlock_t f_lock; /* f_ep_links, f_flags, no IRQ */ atomic_long_t f_count; unsigned int f_flags;//文件标识,O_RDONLY,O_NONBLOCK,O_SYNC fmode_t f_mode;//文件读写模式 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;//文件私有数据 #ifdef CONFIG_EPOLL /* Used by fs/eventpoll.c to link all the hooks to this file */ struct list_head f_ep_links; #endif /* #ifdef CONFIG_EPOLL */ struct address_space *f_mapping; #ifdef CONFIG_DEBUG_WRITECOUNT unsigned long f_mnt_write_state; #endif };要点:文件读写模式mode,标识f_flags,私有数据指针private_data,广泛用于设备驱动中,指向自定义用于描述设备的结构体。
驱动程序中常用如下类似代码检测用户打开文件的读写方式
if(file->f_mode & FMODE_WRITE) { } if(file->f_mode & FMODE_READ) { }以下代码用于判断以阻塞还是非阻塞方式打开设备
if(file->f_flags & O_NONBLOCK) pr_debug("open: non-blocking\n"); else pr_debug("open: blocking\n");2.inode结构体
VFS inode包含文件的各种信息,eg:大小,权限等,是linux管理文件系统的最小单位,也是文件系统连接任何子目录,文件的桥梁
struct inode { struct hlist_node i_hash; struct list_head i_list; /* backing dev IO list */ struct list_head i_sb_list; struct list_head i_dentry; unsigned long i_ino; atomic_t i_count; unsigned int i_nlink; uid_t i_uid;//inode拥有者的id gid_t i_gid;//inode所属的群组id dev_t i_rdev;//若是设备文件,记录设备的设备号 u64 i_version; loff_t i_size; #ifdef __NEED_I_SIZE_ORDERED seqcount_t i_size_seqcount; #endif struct timespec i_atime;//inode最近一次存钱时间 struct timespec i_mtime;//inode最近一次修改时间 struct timespec i_ctime;//inode的产生时间 blkcnt_t i_blocks;//inode所使用的block数,一个block为512byte unsigned int i_blkbits;//inode做I/O时的区块大小 unsigned short i_bytes; umode_t i_mode;//inode的权限 spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ struct mutex i_mutex; struct rw_semaphore i_alloc_sem; const struct inode_operations *i_op; const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ struct super_block *i_sb; struct file_lock *i_flock; struct address_space *i_mapping; struct address_space i_data; #ifdef CONFIG_QUOTA struct dquot *i_dquot[MAXQUOTAS]; #endif struct list_head i_devices; union { struct pipe_inode_info *i_pipe; struct block_device *i_bdev;//块设备 struct cdev *i_cdev;//字符设备 }; __u32 i_generation; #ifdef CONFIG_FSNOTIFY __u32 i_fsnotify_mask; /* all events this inode cares about */ struct hlist_head i_fsnotify_mark_entries; /* fsnotify mark entries */ #endif #ifdef CONFIG_INOTIFY struct list_head inotify_watches; /* watches on this inode */ struct mutex inotify_mutex; /* protects the watches list */ #endif unsigned long i_state; unsigned long dirtied_when; /* jiffies of first dirtying */ unsigned int i_flags; atomic_t i_writecount; #ifdef CONFIG_SECURITY void *i_security; #endif #ifdef CONFIG_FS_POSIX_ACL struct posix_acl *i_acl; struct posix_acl *i_default_acl; #endif void *i_private; /* fs or device private pointer */ };二.file_operations结构体
struct file_operations { struct module *owner;//一般为THIS_MODULE loff_t (*llseek) (struct file *, loff_t, int);//修改文件当前读写位置 ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);//从设备中同步读写数据,成功则返回读取的字节数,失败返回负值 ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);//向设备发送数据,成功返回写入的字节数 ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); int (*readdir) (struct file *, void *, filldir_t);//读取目录 unsigned int (*poll) (struct file *, struct poll_table_struct *);//轮询,判断目前是否可以进行非阻塞的读取或写入 int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);//执行设备I/O控制命令 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *);//用于请求将设备内存映射到进程地址空间 int (*open) (struct inode *, struct file *); int (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, struct dentry *, int datasync); int (*aio_fsync) (struct kiocb *, int datasync); int (*fasync) (int, struct file *, int); int (*lock) (struct file *, int, struct file_lock *); ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); int (*check_flags)(int); int (*flock) (struct file *, int, struct file_lock *); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); int (*setlease)(struct file *, long, struct file_lock **); };
相关文章推荐
- 【linux驱动笔记】字符设备驱动相关数据结构与算法
- 【linux驱动笔记】字符设备驱动相关数据结构与算法
- 字符设备驱动--- 数据结构 设备注册struct cdev , 注销
- linux 学习笔记--字符设备驱动相关数据结构
- 字符设备驱动开发之数据结构
- 玩转设备远程,一张结构图看清楚如何实现PLC数据远程传输
- linux内核中usb系统主要的数据结构
- ffmpeg主要数据结构及其之间的关系
- 数组字符串系列之:判断一个输入字符串中的每个字符唯一,只能使用基本的数据结构
- (模板题)sdut 2125 数据结构实验之串二:字符串匹配(KMP)
- sprintf 编辑 sprintf指的是字符串格式化命令,主要功能是把格式化的数据写入某个字符串中。sprintf 是个变参函数。使用sprintf 对于写入buffer的字符数是没有
- 数据结构之字符串
- 网络设备驱动程序数据结构
- Linux 字符设备驱动结构(四)—— file_operations 结构体知识解析
- Linux-块设备-数据结构
- Linux 字符设备驱动结构(一)—— cdev 结构体、设备号相关知识解析
- Linux 字符设备驱动结构(二)—— 自动创建设备节点
- 通达OA工作流主要表的数据结构
- START WITH CONNECT BY PRIOR子句实现递归查询,主要用于查询数据中的树型结构关系[父子关系]