实验7-设备管理实验 ppt

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

块设备驱动程序的注册过程如图实7-4所示:
7.3

实验内容
字符类型设备的驱动程序 块类型设备的驱动程序
7.3.1

字符类型设备的驱动程序
字符设备驱动程序要用到的数据结构定义: struct device_struct { const char *name; struct file_operations *chops; }; static struct device_struct chrdevs[MAX_CHRDEV]; typedef struct Scull_Dev { void **data; int quantum; // 当前容量的大小。 int qset; // 当前数组的大小。 unsigned long size; unsigned int access_key; // 由sculluid 和scullpriv 使用的存取字段。 unsigned int usage; //当字符设备正使用时加锁。 struct Scull_Dev *next; // 指向下一字符设备 } scull;
服务于I/O请求的子程序
中断服务子程序
图实7-3 设备驱动程序的组织结构
设备驱动程序的代码
设备驱动程序是一些函数和数据结构的集 合,这些函数和数据结构是为实现设备管 理的一个简单接口。操作系统内核使用这 个接口来请求驱动程序对设备进行I/O操 作。甚至,我们可以把设备驱动程序看成 是一个抽象数据类型,它为计算机中的每 个硬件设备都建立了一个通用函数接口。 由于一个设备驱动程序就是一个模块,所 以在内核内部用一个file结构来识别设备 驱动程序,而且内核使用file_operations 结构来访问设备驱动程序中的函数。
块设备的结构
块设备的结构即块设备的开关表。当块设备注册到内核后,块设备的名字和相关操 作被添加到device_struct结构类型的blkdevs全局数组中,称blkdevs为块设备的开 关表。下面以一个简单的例子说明块设备驱动程序中块设备结构的定义:(假设设 备名为sbull) **** file_operations结构定义如下,即定义sbull设备的_fops ****
blk_dev_struct结构
块设备的注册

static struct
{
const char *name; struct block_device_operations *bdops; } blkdevs[MAX_BLKDEV]; 对块设备驱动程序进行注册的调用格式为: int register_blkdev(unsigned int major,const char *name,struct block_device_operations *bdops)
用于字符设备的I/O调用主要有:open()、release()、read()、write()和ioctl()。
open()函数 static int scull_open(struct inode *inode,struct file *filp) { …… …… MOD_INC_USE_COUNT; return 0; } release()函数 static int scull_release(struct inode *inode,struct file *filp) { …… …… MOD_DEC_USE_COUNT; return 0; }
字符设备驱动程序入口点
字符设备驱动程序入口点主要包括初始化字符设备、字符设备的I/O调用和 中断。在引导系统时,每个设备驱动程序通过其内部的初始化函数init()对 其控制的设备及其自身初始化。字符设备初始化函数为chr_dev_init(),包 含在/linux/drivers/char/mem.c中,它的主要功能之一是在内核中登记设备 驱动程序。具体调用是通过register_chrdev()函数。 register_chrdev()函数定义如下: #include <linux/fs.h> #include <linux/errno.h> int register_chrdev (unsigned int major,const char *name,struct file_operation *fops);
字符设备的结构
字符设备的结构device_struct即字符设备的开关表。当字符设备注册 到内核后,字符设备的名字和相关操作被添加到device_struct结构类 型的chrdevs全局数组中,称chrdevs为字符设备的开关表。下面以一 个简单的例子说明字符设备驱动程序中字符设备结构的定义:(假设设 备名为scull) **** file_operations结构定义如下,即定义chr设备的_fops **** static int scull_open(struct inode *inode,struct file *filp); //打开字符设备。 static int scull_release(struct inode *inode,struct file*filp); //释放字符设备。 static ssize_t scull_write(struct inode *inode,struct file *filp, const char *buffer,int count); //将数据送往字符设备。 static ssize_t scull_read(struct inode *inode,struct file *filp, char *buffer,int count); //从字符设备读出数据,写入用户空间。 static int scull_ioctl(struct inode *inode,struct file *filp, unsigned long int cmd,unsigned long arg); //字符设备的控制操作。
实验7 设备管理实验
7.1
实验目的
了解Linux操作系统中的设备驱动程序的组成 编写简单的字符设备驱动程序并进行测试 编写简单的块设备的驱动程序,并进行测试 理解Linux操作系统的设备管理机制
7.2
准备知识
图实7-1 字符设备和块设备驱动程序和接口
图实7-2 设备驱动程序与外界的接口
自动配置和初始化子程序
字符设备的结构
struct file_operations chr_fops = { NULL, // seek,改变字符设备的操作位置。 scull_read, // read,字符设备的读操作。 scull_write, // write,字符设备的写操作。 NULL, // readdir,读取某个子目录中的内容。 NULL, // poll,允许应用程序响应来自字符设备的事件。 scull_ioctl, // ioctl,字符设备的控制操作。 NULL, // mmap,字符设备地址空间到用户地址空间的映射。 scull_open, // open,字符设备的打开操作。 NULL, // flush,冲掉缓冲区的数据,对字符设备无用。 scull_release, // release,字符设备的释放操作。 NULL, // fsync,同步内存与磁盘上的数据状态,把输出 缓冲区里尚未写到磁盘的数据写出去。 NULL, // fasync,改变字符设备行为。 NULL, // check media change,检查自上次操作后, 介质(软盘和CD-ROM)是否更换。 NULL, // revalidate,若更换了介质,则更新信息。 NULL // lock,锁定字符设备操作。 };
字符设备的注册
Linux系统通过调用register_chrdev()向系统注册字符 型设备驱动程序 register_chrdev()定义如下: #include <linux/fs.h> #include <linux/errno.h> int register_chrdev (unsigned int major, const char *name, struct file_operations *ops)
图实7-8
函数scull_release()的流程图
图实7-9
字符设备驱动程序的测试函数流程图
测试函数: #cat /proc/devices | awk ”\\$2==\ ”chrdev\”{ print\\$1}”
图实7-10
7.3.2 块类型设备的驱动程序
struct device_struct { const char *name; struct file_operations *chops; }; static struct device_struct blkdevs[MAX_BLKDEV]; struct sbull_dev { void **data; int quantum; // 当前容量的大小。 int qset; // 当前数组的大小。 unsigned long size; unsigned int access_key; // 由sbulluid和sbullpriv使用的存取字段。 unsigned int usage; //当块设备正使用时加锁。 unsigned int new_msg; struct sbull_dev *next; // 指向下一块设备。 }; extern struct sbull_dev *sbull; // 块设备信息
Biblioteka Baidu
块设备驱动程序描述符
块设备驱动程序描述符是一个blk_dev_struct类型的数据结 构,其定义如下: struct blk_dev_struct { // queue_proc 指向的队列必须为原子操作,即指令 的执行是一次性完成的,不能间断。 request_queue_t request_queue ; queue_proc *queue ; void *data ; }
struct file_operations blk_fops = { NULL, // seek,改变块设备的操作位置。 block_read, //块设备的读操作,为内核函数。 block_write, //块设备的写操作,为内核函数。 NULL, // readdir,读取某个子目录中的内容。 NULL, // poll,允许应用程序响应来自块设备的事件。 sbull_ioctl, // ioctl,块设备的控制操作。 NULL, // mmap,块设备地址空间到用户地址空间的映射。 sbull_open, // open,块设备的打开操作。 NULL, // flush,冲掉块设备缓冲区的数据。 sbull_release, // release,块设备的释放操作。 block_fsync, //同步内存与磁盘上的数据状态,把输出缓冲区里尚未写到磁盘的数据写出去。为内核函数。 NULL, // fasync,改变块设备行为。 sbull_check_media_change, // check media change,检查自上次操作后,介质(软盘和CD-ROM)是否更换。 NULL, // revalidate,若更换了介质,则更新信息。 NULL // lock,锁定块设备操作。 };

函数scull_open()的流程图
开始 该设备的用户数目增加1; MOD_INC_USE_COUNT; 打印 “This chrdev is in open!” 成功,返回0 结束
图实7-5
函数scull_write()的流程图
图实7-6
函数scull_read()的流程图
图实7-7
函数scull_ioctl()的流程图
块设备驱动程序入口点

块设备驱动程序入口点主要包括初始化块设备、块设备 的I/O调用和中断。块设备的I/O调用ioctl()、open()、 release()与字符设备类似。 块设备与字符设备最大的不同在于设备的读写操作。块 设备使用通用block_read()和block_write()函数来进行数 据读写。这两个通用函数向请求表中增加读写请求,这 样内核可以对请求顺序安排优先级(通过 ll_rw_block())。由于是对内存缓冲区而不是对设备进 行操作,因而它们能加快读写请求。如果内存中没有要 读入的数据或者没有要写入设备对应的缓冲区,那么就 需要真正地执行数据传输操作。这是通过数据结构 blk_dev_struct中的request_fn来完成的(见 include/linux /blkdev.h)。
相关文档
最新文档