您的位置:首页 > 理论基础 > 数据结构算法

字符设备驱动开发之数据结构

2011-03-28 10:21 295 查看
接下来的几部分,我想通过简单的字符设备程序来了解设备驱动开发的基本原理以及流程。
由于用户程序是通过设备文件来和具体的硬件打交道,而对设备文件的操作无非是通过一系列的系统调用如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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息