Linux之设备驱动学习简过程<三>(不断添加中)

 为了学好字符设备驱动,一些相关结构不得不了解。。。于是,通过Source Insight打开内核。。。我浏览到了驱动重要的相关结构

*用户跟驱动关系:用户空间的read、write等--->linux系统调用--->间接调用设备驱动程序中file_operations结构中的函数(看个例子理解下)

1.struct file_operations学驱动必须了解的结构 

 

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 *);		//写数据到设备
 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);	//命令控制设置
 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 **);
};


2.文件结构 代表一个打开的文件描述符,它不是专门给驱动程序使用的,系统中每一个打开的文件在内核中都有一个关联的struct file。它由内核在open时创建,并传递给在文件上操作的任何函数,直到最后关闭。当文件的所有实例都关闭之后,内核释放这个数据结构

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;
 } 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;	//文件标识,可写,可读
 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
};



 

3.内核中用inode结构表示具体的文件

struct inode {
 struct hlist_node i_hash;
 struct list_head i_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;
 gid_t   i_gid;
 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;
 struct timespec  i_mtime;
 struct timespec  i_ctime;
 unsigned int  i_blkbits;
 blkcnt_t  i_blocks;
 unsigned short          i_bytes;
 umode_t   i_mode;
 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;
 };
 int   i_cindex;

 __u32   i_generation;

#ifdef CONFIG_DNOTIFY
 unsigned long  i_dnotify_mask; /* Directory notify events */
 struct dnotify_struct *i_dnotify; /* for directory notifications */
#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
 void   *i_private; /* fs or device private pointer */
};


参考资料:http://www.cnblogs.com/QJohnson/archive/2011/06/24/2089414.html

4.cdev结构

在Linux2.6内核中一个字符设备用cdev结构来描述,其定义如下:

struct cdev {
       struct kobject kobj;
       struct module *owner;   //所属模块
        const struct file_operations *ops;   
                //文件操作结构,在写驱动时,其结构体内的大部分函数要被实现
        struct list_head list;
       dev_t dev;          //设备号,int 类型,高12位为主设备号,低20位为次设备号
        unsigned int count;
};


可以使用如下宏调用来获得主、次设备号:
MAJOR(dev_t dev)
MINOR(dev_t dev)
MKDEV(int major,int minor) //通过主次设备号来生成dev_t

5.混杂设备miscdevice结构

struct miscdevice  {
 int minor;
 const char *name;
 const struct file_operations *fops;
 struct list_head list;
 struct device *parent;
 struct device *this_device;
};


 

 

你可能感兴趣的:(Linux之设备驱动学习简过程<三>(不断添加中))