字符设备驱动开发之数据结构
2011-03-28 10:21
295 查看
接下来的几部分,我想通过简单的字符设备程序来了解设备驱动开发的基本原理以及流程。
由于用户程序是通过设备文件来和具体的硬件打交道,而对设备文件的操作无非是通过一系列的系统调用如open,close,read,write等来实现;对具体硬件设备的读写时通过设备驱动程序来完成。但是如何将系统调用和设备驱动程序联系起来呢?这里就涉及到一个非常重要的数据结构:
这个结构的每一个成员的名字都对应着一个系统调用。每个驱动程序注册时都会绑定这样的一个数据结构。当用户进程利用系统调用在对设备文件进行诸如read/write操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数。这是linux的设备驱动程序工作的基本原理。既然是这样,则编写设备驱动程序的主要工作就是编写子函数,并填充file_operations的各个域。
struct file代表一个打开的文件,在执行file_operations中的open操作时被创建,file指针在用户控件定义;
该结构的说明如下:
struct inode 结构用来在内核中代表一个文件,同一个文件可能被打开多次,有多个file结构,但是只有一个inode结构。
其中有两个非常重要的成员,
dev_t i_rdev 保存设备文件的设备号
struct cdev *i_cdev 代表该文件对应的字符设备结构
参考网址:
http://www.embedu.org/Column/Column09.htm
http://space.itpub.net/14805538/viewspace-445624
由于用户程序是通过设备文件来和具体的硬件打交道,而对设备文件的操作无非是通过一系列的系统调用如open,close,read,write等来实现;对具体硬件设备的读写时通过设备驱动程序来完成。但是如何将系统调用和设备驱动程序联系起来呢?这里就涉及到一个非常重要的数据结构:
/* 1526 * NOTE: 1527 * all file operations except setlease can be called without 1528 * the big kernel lock held in all filesystems. 1529 */ 1530struct file_operations { 1531 struct module *owner; 1532 loff_t (*llseek) (struct file *, loff_t, int); 1533 ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); 1534 ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); 1535 ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t); 1536 ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t); 1537 int (*readdir) (struct file *, void *, filldir_t); 1538 unsigned int (*poll) (struct file *, struct poll_table_struct *); 1539 long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); 1540 long (*compat_ioctl) (struct file *, unsigned int, unsigned long); 1541 int (*mmap) (struct file *, struct vm_area_struct *); 1542 int (*open) (struct inode *, struct file *); 1543 int (*flush) (struct file *, fl_owner_t id); 1544 int (*release) (struct inode *, struct file *); 1545 int (*fsync) (struct file *, int datasync); 1546 int (*aio_fsync) (struct kiocb *, int datasync); 1547 int (*fasync) (int, struct file *, int); 1548 int (*lock) (struct file *, int, struct file_lock *); 1549 ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); 1550 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); 1551 int (*check_flags)(int); 1552 int (*flock) (struct file *, int, struct file_lock *); 1553 ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); 1554 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); 1555 int (*setlease)(struct file *, long, struct file_lock **); 1556 long (*fallocate)(struct file *file, int mode, loff_t offset, 1557 loff_t len); 1558};
这个结构的每一个成员的名字都对应着一个系统调用。每个驱动程序注册时都会绑定这样的一个数据结构。当用户进程利用系统调用在对设备文件进行诸如read/write操作时,系统调用通过设备文件的主设备号找到相应的设备驱动程序,然后读取这个数据结构相应的函数指针,接着把控制权交给该函数。这是linux的设备驱动程序工作的基本原理。既然是这样,则编写设备驱动程序的主要工作就是编写子函数,并填充file_operations的各个域。
struct file代表一个打开的文件,在执行file_operations中的open操作时被创建,file指针在用户控件定义;
该结构的说明如下:
struct file { 940 /* 941 * fu_list becomes invalid after file_free is called and queued via 942 * fu_rcuhead for RCU freeing 943 */ 944 union { 945 struct list_head fu_list; 946 struct rcu_head fu_rcuhead; 947 } f_u; 948 struct path f_path; 949#define f_dentry f_path.dentry 950#define f_vfsmnt f_path.mnt 951 const struct file_operations *f_op; 952 spinlock_t f_lock; /* f_ep_links, f_flags, no IRQ */ 953#ifdef CONFIG_SMP 954 int f_sb_list_cpu; 955#endif 956 atomic_long_t f_count; 957 unsigned int f_flags; 958 fmode_t f_mode; 959 loff_t f_pos; 960 struct fown_struct f_owner; 961 const struct cred *f_cred; 962 struct file_ra_state f_ra; 963 964 u64 f_version; 965#ifdef CONFIG_SECURITY 966 void *f_security; 967#endif 968 /* needed for tty driver, and maybe others */ 969 void *private_data; 970 971#ifdef CONFIG_EPOLL 972 /* Used by fs/eventpoll.c to link all the hooks to this file */ 973 struct list_head f_ep_links; 974#endif /* #ifdef CONFIG_EPOLL */ 975 struct address_space *f_mapping; 976#ifdef CONFIG_DEBUG_WRITECOUNT 977 unsigned long f_mnt_write_state; 978#endif 979}; 980
struct inode 结构用来在内核中代表一个文件,同一个文件可能被打开多次,有多个file结构,但是只有一个inode结构。
struct inode { 741 /* RCU path lookup touches following: */ 742 umode_t i_mode; 743 uid_t i_uid; 744 gid_t i_gid; 745 const struct inode_operations *i_op; 746 struct super_block *i_sb; 747 748 spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ 749 unsigned int i_flags; 750 struct mutex i_mutex; 751 752 unsigned long i_state; 753 unsigned long dirtied_when; /* jiffies of first dirtying */ 754 755 struct hlist_node i_hash; 756 struct list_head i_wb_list; /* backing dev IO list */ 757 struct list_head i_lru; /* inode LRU list */ 758 struct list_head i_sb_list; 759 union { 760 struct list_head i_dentry; 761 struct rcu_head i_rcu; 762 }; 763 unsigned long i_ino; 764 atomic_t i_count; 765 unsigned int i_nlink; 766 dev_t i_rdev; 767 unsi 4000 gned int i_blkbits; 768 u64 i_version; 769 loff_t i_size; 770#ifdef __NEED_I_SIZE_ORDERED 771 seqcount_t i_size_seqcount; 772#endif 773 struct timespec i_atime; 774 struct timespec i_mtime; 775 struct timespec i_ctime; 776 blkcnt_t i_blocks; 777 unsigned short i_bytes; 778 struct rw_semaphore i_alloc_sem; 779 const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ 780 struct file_lock *i_flock; 781 struct address_space *i_mapping; 782 struct address_space i_data; 783#ifdef CONFIG_QUOTA 784 struct dquot *i_dquot[MAXQUOTAS]; 785#endif 786 struct list_head i_devices; 787 union { 788 struct pipe_inode_info *i_pipe; 789 struct block_device *i_bdev; 790 struct cdev *i_cdev; 791 }; 792 793 __u32 i_generation; 794 795#ifdef CONFIG_FSNOTIFY 796 __u32 i_fsnotify_mask; /* all events this inode cares about */ 797 struct hlist_head i_fsnotify_marks; 798#endif 799 800#ifdef CONFIG_IMA 801 /* protected by i_lock */ 802 unsigned int i_readcount; /* struct files open RO */ 803#endif 804 atomic_t i_writecount; 805#ifdef CONFIG_SECURITY 806 void *i_security; 807#endif 808#ifdef CONFIG_FS_POSIX_ACL 809 struct posix_acl *i_acl; 810 struct posix_acl *i_default_acl; 811#endif 812 void *i_private; /* fs or device private pointer */ 813};
其中有两个非常重要的成员,
dev_t i_rdev 保存设备文件的设备号
struct cdev *i_cdev 代表该文件对应的字符设备结构
参考网址:
http://www.embedu.org/Column/Column09.htm
http://space.itpub.net/14805538/viewspace-445624
相关文章推荐
- linux驱动开发--字符设备:通过cdd_cdev结构中的led变量区分是哪个节点,private_data使用
- 字符设备驱动结构与开发
- linux驱动开发之字符设备--内核和用户空间数据的交换(ioctl)
- Linux驱动开发学习--字符设备驱动结构
- 【linux驱动笔记】字符设备驱动相关数据结构与算法
- 【linux驱动笔记】字符设备驱动相关数据结构与算法
- linux驱动开发之字符设备--内核和用户空间数据的交换(read write)
- linux驱动开发之字符设备--私有数据和container_of
- Hasen的linux设备驱动开发学习之旅--使用文件私有数据的字符设备驱动
- linux驱动开发之字符设备--内核和用户空间数据的交换(sysfs)
- 字符设备驱动--- 数据结构 设备注册struct cdev , 注销
- 字符设备驱动结构与开发
- linux 学习笔记--字符设备驱动相关数据结构
- linux设备驱动开发学习之旅--使用文件私有数据的字符设备驱动
- Linux 字符设备驱动开发基础(三)—— read()、write() 相关函数解析
- Linux 字符设备驱动开发基础(五)—— ioremap() 函数解析
- Linux设备驱动开发详解-Note(13)--- 字符设备驱动(2)
- Linux内核开发之简单字符设备驱动(下)
- Linux字符设备驱动结构
- 第12课第4.1节 字符设备驱动程序之中断方式的按键驱动_Linux异常处理结构