snifer

【原创】嵌入式系统之file_opration结构分析

1
阅读(1946)

天气很冷,跟朋友们讨论的很激烈,今天就写一下我们讨论的file_opration结构,在此感谢几位一起讨论的群友。

首先来看file_operations 在内核中定义linux/fs.h

struct file_operations {

struct module *owner;

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 *);

unsigned int (*poll) (struct file *, struct poll_table_struct *);

int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);

int (*mmap) (struct file *, struct vm_area_struct *);

int (*open) (struct inode *, struct file *);

int (*release) (struct inode *, struct file *);

int (*fsync) (struct file *, struct dentry *, int datasync);

……

};

其中

int(*open)(struct inode*,struct file *)

增加使用计数,检查错误,如果未初始化,则调用初始化,识别次设备号,如果必要,更新f_op指针,分配并填写被置于filp->private_data的数据结构:

int(*realse)(struct inode*,struct file*)

open逆操作:

ssize_t (*read)(struct file*,char *,size_t,loff_t*)

用户空间和内核空间数据交互,用户空间指针和内核指针,驱动调用copy_to_user()将数据返回给用户

ssize_t(*write)(struct file*,const char*,size_t,loff_t*)

驱动调用copy_from_user(),从而将用户数据读到本地buffer。

int (*mmap)(struct file*, struct vm_area_struct*)

驱动中提供该方法用于支持用户mmap操作,用户将设备内存区映射到进程的地址空间,直接操作该物理内存提高效率,典型的有framebuffer,sound,capture等驱动。

int(*ioctl)(struct inode*,struct file*,unsigned int cmd,unsigned long arg) 

驱动程序一般需支持通过Ioctl实现各种控制与参数设置,如串口可设置波特率等多参数 }cmd变量存放命令,驱动代码根据cmd里面的值进行switch-cas处理分支 }arg存放参数,如为整数,可直接使用。如为指针,驱动程序首先要检查指针的合法性 }int access_ok(int type, const void *addr, unsigned long size); 检查通过后可以使用 }驱动程序还可通过int capable(int capability)函数来确定调用进程是否有权执行操作。

用户系统调用:

int ioctl(int fd, int cmd, ...);

cmd命令码格式,用户空间与Linux内核中定义需一致: 

     ___________________________________

      | 设备类型 | 序列号 | 方向 |数据尺寸|

      |----------    |--------    |------  |--------|

      | 8 bit         |  8 bit      |2 bit  |8~14 bit|

这一部分为file_opration结构基础,等我捂捂手,在写之file_opration的应用。