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

来源:互联网 发布:java sleep 编辑:程序博客网 时间:2024/05/16 11:35

 为了学好字符设备驱动,一些相关结构不得不了解。。。于是,通过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;};


 

 

原创粉丝点击