為了學好字元裝置驅動,一些相關結構不得不瞭解。。。於是,通過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;};