书名:《Linux设备驱动开发详解》第二版
主机环境:Linux version 2.6.25-14.fc9.i686@Fedora
arm-linux-gcc版本:version 4.4.1
开发板:mini2440-256M
版权信息:版权归作者M.Bing和博客园共同所有,可以随意转载,但请保留此条信息!
备注:由于作者水平有限,文章难免出错,欢迎大家指正,共同学习。
一、字符设备简介 在Linux2.6内核中,使用cdev结构描述一个字符设备,cdev结构如下所示
复制代码 struct cdev { struct kobject kobj; struct module owner; struct file_operations ops; /文件操作结构体/ struct list_head list; dev_t dev; /设备号 32位,其中12位主设备号,20次设备号/ unsigned int count; }; 复制代码 可以从dev_t获得主设备号和次设备号:
MAJOR(dev_t dev)
MINOR(dev_t dev)
可以使用下面的宏通过主设备号和次设备号生成dev_t:
MKDEV(int major, int minor)
cdev结构内部还有一个重要的结构体:file_operations,其定义了字符设备驱动提供给虚拟文件系统的接口函数。
在Linux2.6内核中使用以下函数操作cdev结构体:
void cdev_init(struct cdev , struct file_operationd );/这个函数将cdev和file_operations联合在一起/ struct cdev *cdev_alloc(void); void cdev_put(struct cdev *,dev_t, unsigned); int cdev_add(struct cdev *, dev_t, unsigned); void cdev_del(struct cdev *); 各个函数的功能从其函数名就可以看出。
二、file_operations结构体 在上面一节说了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(aio_read) (struct kiocb , char __user *, size_t, loff_t); ssize_t(write) (struct file , const char __user *, size_t, loff_t *); ssize_t(aio_write) (struct kiocb , const char __user *, size_t, 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); int (mmap) (struct file , struct vm_area_struct *); int (open) (struct inode , struct file *); int (flush) (struct file ); 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 (lo