Simple process of Device Driver learning in Linux (continuous addition)

Source: Internet
Author: User

In order to learn the driver of character devices, we have to understand some related structures... So, open the kernel through Source Insight... I browsed important driver structures.

* User-driver relationship: user space read, write, etc. ---> linux System Call ---> indirectly call the functions in the file_operations structure of the device driver (see the example below)

1. structure required by struct file_operations driver

 

Struct file_operations {struct module * owner; // driver module pointer loff_t (* llseek) (struct file *, loff_t, INT); // file read/write location ssize_t (* read) (struct file *, char _ User *, size_t, loff_t *); // read data from the device ssize_t (* write) (struct file *, const char _ User *, size_t, loff_t *); // write data to the device 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 *); // whether reading and writing of file descriptors blocks int (* IOCTL) (struct inode *, struct file *, unsigned int, unsigned long ); // command control settings 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 *); // The device memory is mapped to the process space int (* open) (struct inode *, struct file *); // open the INT (* flush) (struct file *, fl_owner_t ID) of the device; int (* release) (struct inode *, struct file *); // disable the 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); 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. File structureRepresents an opened file descriptor, which is not used by the driver. Each opened file in the system has an associated struct file in the kernel. It is created when the kernel is open and passed to any function operated on the file until it is closed. When all instances of the file are closed, the kernel releases the data structure.

Struct file {/** fu_list becomes invalid after file_free is called and queued via * Waiting for RCU freeing */union {struct list_head fu_list; struct rcu_head fu_rcuhead;} f_u; struct path f_path; // file path # define f_dentry f_path.dentry # define paif_path.mnt const struct file_operations * f_op; // file operator structure: spinlock_t f_lock;/* f_ep_links, f_flags, no IRQ */limit f_count; unsigned int f_flags; // File ID, writable, readable fmode_t f_mode; loff_t f_pos; // file read/write location 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 extends unsigned long f_mnt_write_state; # endif };

 

3. The inode structure is used in the kernel to indicate specific files.

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 */};

References: http://www.cnblogs.com/QJohnson/archive/2011/06/24/2089414.html

4. cdev Structure

The cdev structure is used to describe a character device in the Linux2.6 kernel. Its definition is as follows:

Struct cdev {struct kobject kobj; struct module * owner; // The const struct file_operations * ops module; // file operation structure. When writing a driver, most of the functions in its structure are implemented by struct list_head list; dev_t dev; // device number, int type, with a height of 12 digits as the primary device number, the second device number is unsigned int count for the lower 20 bits ;};

You can use the following macro call to obtain the master and secondary device numbers:
MAJOR (dev_t dev)
MINOR (dev_t dev)
MKDEV (int major, int minor) // use the Primary and Secondary device numbers to generate dev_t

5. miscdevice structure of hybrid Devices

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

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.