第三章 三个数据结构以及字符设备的注册
2011-07-30 16:25
183 查看
上一篇讲到了注册设备编号,显然,注册设备编号只是编写驱动代码的第一个步骤。为了完成以后的一些步骤,先介绍三个重要的内核数据结构。
file_operation囊括了所有设备操作到设备号的链接。在linux中驱动以文件的方式存在,而file_operation则是对文件(这里是是字符设备)的所有操作的集合。由于file_operation的成员太多,而当前scull项目仅仅用到了其中的几个。 scull项目的file_operation初始化如下:
owner指向拥有这个结构的模块,几乎所有情况下,它的值都是THIS_MODULE,这是一个定义在<linux/module.h>中的宏;llseek 方法用作改变文件中的当前读/写位置, 并且新位置作为(正的)返回值;read用来从设备中获取数据;write用来发送数据给设备;.ioctl 用来发出设备特定命令(非read或write);open为打开设备文件,显然这应该是对设备文件进行的第一个操作;.release 释放文件结构。
file数据结构代表一个打开的文件(记住设备被当做了文件)。如同file_operation指定了操作的集合,file就是这些操作的目标对象了。
inode数据结构也表示文件,不过他跟file数据结构不同(估计这个区别以后才能了解)。对于编写驱动来说,这个数据结构就两个字段有用。dev_t i_rdev代表设备编号,struct cdev *i_cdev;代表一个字符设备。详细的信息到使用的时候再深入研究。
要说明的是,linux源代码在初始化这些数据结构的时候一般都是用c语言的标记式结构初始化语法。
linux内核在内部使用类型struct cdev来代表字符设备。而在scull中,使用一个自定义的struct scull_dev类型的
结构来表示每个设备,这个结构包括了一个struct cdev结构:
初始化这一结构并注册的函数如下:
这样就完成了一个字符设备的初始化和注册。
file_operation囊括了所有设备操作到设备号的链接。在linux中驱动以文件的方式存在,而file_operation则是对文件(这里是是字符设备)的所有操作的集合。由于file_operation的成员太多,而当前scull项目仅仅用到了其中的几个。 scull项目的file_operation初始化如下:
struct file_operations scull_fops = { .owner = THIS_MODULE, .llseek = scull_llseek, .read = scull_read, .write = scull_write, .ioctl = scull_ioctl, .open = scull_open, .release = scull_release, };
owner指向拥有这个结构的模块,几乎所有情况下,它的值都是THIS_MODULE,这是一个定义在<linux/module.h>中的宏;llseek 方法用作改变文件中的当前读/写位置, 并且新位置作为(正的)返回值;read用来从设备中获取数据;write用来发送数据给设备;.ioctl 用来发出设备特定命令(非read或write);open为打开设备文件,显然这应该是对设备文件进行的第一个操作;.release 释放文件结构。
file数据结构代表一个打开的文件(记住设备被当做了文件)。如同file_operation指定了操作的集合,file就是这些操作的目标对象了。
inode数据结构也表示文件,不过他跟file数据结构不同(估计这个区别以后才能了解)。对于编写驱动来说,这个数据结构就两个字段有用。dev_t i_rdev代表设备编号,struct cdev *i_cdev;代表一个字符设备。详细的信息到使用的时候再深入研究。
要说明的是,linux源代码在初始化这些数据结构的时候一般都是用c语言的标记式结构初始化语法。
linux内核在内部使用类型struct cdev来代表字符设备。而在scull中,使用一个自定义的struct scull_dev类型的
结构来表示每个设备,这个结构包括了一个struct cdev结构:
struct scull_dev { struct scull_qset *data; /* Pointer to first quantum set */ int quantum; /* the current quantum size */ int qset; /* the current array size */ unsigned long size; /* amount of data stored here */ unsigned int access_key; /* used by sculluid and scullpriv */ struct semaphore sem; /* mutual exclusion semaphore */ struct cdev cdev; /* Char device structure */ };
初始化这一结构并注册的函数如下:
static void scull_setup_cdev(struct scull_dev *dev, int index) { int err, devno = MKDEV(scull_major, scull_minor + index); cdev_init(&dev->cdev, &scull_fops); dev->cdev.owner = THIS_MODULE; dev->cdev.ops = &scull_fops; err = cdev_add (&dev->cdev, devno, 1); /* Fail gracefully if need be */ if (err) printk(KERN_NOTICE "Error %d adding scull%d", err, index); }
这样就完成了一个字符设备的初始化和注册。
相关文章推荐
- 字符设备驱动程序中重要的三个数据结构file_operations、inode、file
- 字符设备驱动程序中重要的三个数据结构file_operations、inode、file
- 字符设备驱动程序中重要的三个数据结构file_operations、inode、file
- 字符设备驱动程序中重要的三个数据结构file_operations、inode、file
- linux 驱动程序 设备模块 设备号 设备文件创建 设备注册 字符驱动设备分析
- Linux驱动编程--字符设备文件注册
- linux注册字符设备和卸载字符设备函数
- linux 驱动程序 设备模块 设备号 设备文件创建 设备注册 字符驱动设备分析
- gendisk,request与bio结构体,以及块设备驱动注册与注销,以及加载与卸载
- 使用register_chrdev注册字符设备
- SDMA相关的数据结构、宏展开及设备函数注册过程
- 第三章字符设备驱动(1)--分配和释放设备号
- linux驱动设备--------字符设备的注册
- 字符设备驱动以及杂项设备驱动
- linux内核字符设备驱动相关的函数以及结构体
- Linux字符设备驱动的注册
- 字符设备、块设备以及网络设备
- linux内核cdev_init系列函数(字符设备的注册)
- linux内核cdev_init系列函数(字符设备的注册)
- 使用cdev_add注册字符设备