资源预览内容
第1页 / 共62页
第2页 / 共62页
第3页 / 共62页
第4页 / 共62页
第5页 / 共62页
第6页 / 共62页
第7页 / 共62页
第8页 / 共62页
第9页 / 共62页
第10页 / 共62页
亲,该文档总共62页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
Linux设备驱动开发余琴2010.3提纲 设备驱动概述 如何编写内核模块 如何编写设备驱动 字符设备驱动实例预备知识:设备控制器的功能及接口 每一个物理设备都有自己的硬件控制器,每一个硬件控制器都有自己的控制和状态寄存器(CSR),不同的设备是不同的; 设备控制器的功能:命令寄存器和译码器(接收和识别命令)、数据寄存器(数据交换)、状态寄存器(设备状态的了解和报告)、地址寄存器(地址识别) 设备控制器与CPU的接口:数据线、地址线、控制线 设备控制器与设备的接口:数据信号、状态信号、控制信号预备知识:系统对设备的管理 设备控制表(DCT):每个设备一张表,表结构如下:设备标识符、设备类型、设备地址或设备号、设备状态、等待队列指针、重复执行的次数和时间、I/O控制器指针 系统设备表(SDT):整个系统一张表,表结构如下:DCT指针、正在使用设备的进程标识、设备驱动程序入口驱动原理:什么是设备驱动? 设备控制器的CSR用于启动和停止设备,初始化设备和诊断它的问题 管理这些硬件控制器的代码不是放在每一个应用程序里边,而是放在 Linux内核中。这些处理或管理硬件控制器的软件就叫做设备驱动程 序。 一般来说,一个驱动程序控制一种硬件设备; Linux核心的设备驱动程序是Linux操作系统的一部分,它运行于核心 态。驱动原理:驱动架构硬件设备驱动块设备字符设备缓冲区文件子系统进程控制子系统进程调度内存管理调进程间通讯系统调用接口硬件层内核层内核层用户层库函数用户程序驱动原理:内核何时使用驱动程序? Linux内核使用“设备无关”的I/O子系统来为所有的设备服务。每个设备都提供标准接口给内核,从而尽可能地隐藏了自己的特性。 用户程序使用一些基本的系统调用从设备读取数据并且将它们存入缓冲。 每当一个系统调用被使用时,内核就转到相应的设备驱动例程来操纵硬件。 驱动原理: Linux的I/O子系统驱动原理:Linux设备与文件的关系 Linux将所有外部设备看成是一类特殊文件,称之为“设备文件”,如果说系统调用是Linux内核和应用程序之间的接口,那么设备驱动程序则可以看成是Linux内核与外部设备之间的接口。 设备驱动程序向应用程序屏蔽了硬件在实现上的细节,使得应用程序可以像操作普通文件一样来操作外部设备。驱动原理:设备文件Linux抽象了对硬件的处理,使得所有的硬件设备都可以像普通文件一样来看待:它们可以使用和操作文件相同的、标准的系统调用接口来完成打开、关闭、读写和I/O控制操作,而驱动程序的主要任务也就是要实现这些系统调用函数。Linux系统中的所有硬件设备都使用一个特殊的设备文件来表示,例如,系统中的第一个IDE硬盘在文件系统中使用/dev/hda表示。Linux通过分配设备号来标识每个设备,每个设备文件对应有两个设备号:一个是主设备号,标识该设备的种类,也标识了该设备所使用的驱动程序,有关主设备号分配见linux/include/linux/major.h 。例如软驱主设备号是2,IDE硬盘的主设备号是3;另一个是次设备号,标识使用同一设备驱动程序的不同硬件设备。例如,一台PC有两块IDE硬盘,它们的主设备号都是 3,但是第一个硬盘的次设备号为1,另一个次设备号为2。设备文件的主设备号必须与设备驱动程序在登记该设备时申请的主设备号一致,否则用户进程将无法访问到设备驱动程序。驱动原理:设备驱动程序的主要功能 对设备进行初始化; 使设备投入运行和退出服务; 从设备接收数据并将它们送回内核; 将数据从内核送到设备; 检测和处理设备出现的错误。驱动原理:字符设备和块设备 在Linux操作系统下有两类主要的设备文件:一类是字符设备,另一 类则是块设备。 字符设备是以字节为单位逐个进行I/O操作的设备,在对字符设备发 出读写请求时,实际的硬件I/O紧接着就发生了,一般来说字符设备 中的缓存是可有可无的,而且也不支持随机访问。如鼠标、键盘、串 口 块设备则是利用一块系统内存作为缓冲区,当用户进程对设备进行读 写请求时,驱动程序先查看缓冲区中的内容,如果缓冲区中的数据能 满足用户的要求就返回相应的数据,否则就调用相应的请求函数来进 行实际的I/O操作。如硬盘、光驱等块设备主要是针对磁盘等慢速设 备设计的,其目的是避免耗费过多的CPU时间来等待操作的完成。驱动原理:设备文件与驱动程序的关系 所有已经注册(即已经加载了驱动程序)的硬件设备的主设备号可以 从/proc/devices文件中得到。 使用mknod命令可以创建指定类型的设备文件,同时为其分配相应的 主设备号和次设备号。mknod /dev/device_name device_type major_number minor_number其中:device_name是此设备的文件device_type是此设备的类型,c表示字符设备,b表示块设备例如,建立一个主设备号为6,次设备号为0的字符设备文件/dev/lp0 : # mknod /dev/lp0 c 6 0 当应用程序对某个设备文件进行系统调用时,Linux内核会根据该设 备文件的设备类型和主设备号调用相应的驱动程序,并从用户态进入 到核心态,再由驱动程序判断该设备的次设备号,最终完成对相应硬 件的操作。驱动机制:设备管理 1、设备管理:系统对已经登记的字符设备的管理是由chrdevs来管理 的。 Linux对设备进行访问时,访问文件系统中相应的设备文件,通过文 件系统和文件的属性描述块,可以找到该文件系统或设备对应的设备 号。在实际访问列表时,以chrdevsMAJORMINOR 形式访问。static struct char_device_struct struct char_device_struct *next;unsigned int major;unsigned int baseminor;int minorct;const char *name;struct file_operations *fops;struct cdev *cdev;/* will die */ *chrdevsMAX_PROBE_HASH;驱动机制:I/O请求管理 2、I/O请求管理:系统会把一部分系统内存作为块设备驱动程序与文件系统接口之间的一层缓冲区,每个缓冲区与某台设备中的特定区域相联系,文件系统首先试图查找相应的缓冲区,如未找到才向该设备发出I/O读写请求,由设备驱动程序对这些请求进行处理。驱动机制:中断请求 3、中断请求:设备进行实际的输入/输出时,如果时间过长而始终占用CPU,就会影响系统的效率,所以Linux采用中断的机制。驱动机制:中断与轮询设备被执行某个命令时,如“将读取磁头移动到软盘的第42扇区上”,设备驱动可以从轮询方式和中断方式中选择一种以判断设备是否已经完成此命令。轮询方式意味着需要经常读取设备的状态,一直到设备状态表明请求已经完成为止。如果设备驱动被连接进入内核,这时使用轮询方式将会带来灾难性后果:内核将在此过程中无所事事,直到设备完成此请求。但是轮询设备驱动可以通过使用系统定时器,使核心周期性调用设备驱动中的某个例程来检查设备状态。 定时器过程可以检查命令状态及Linux软盘驱动的工作情况。使用定时器是轮询方式中最好的一种,但更有效的方法是使用中断。 基于中断的设备驱动会在它所控制的硬件设备需要服务时引发一个硬件中断。如以太网设备驱动从网络上接收到一个以太数据报时都将引起中断。Linux内核需要将来自硬件设备的中断传递到相应的设备驱动。这个过程由设备驱动向内核注册其使用的中断来协助完成。此中断处理例程的地址和中断号都将被记录下来。在/proc/interrupts文件中你可以看到设备驱动所对应的中断号及类型。驱动机制:高速缓冲 4、高速缓冲区:为了加速物理设备的访问速度,Linux将块缓冲区放 在cache内,块缓冲区是由buff_head 连成的链表结构。struct buff_head unsigned long b_blocknr 逻辑块号unsigned long b_size 块大小kdev_t b_dev 虚拟设备标志符kdev_t b_rdev 实际设备标志符unsigned long b_state 缓冲区状态标志char * b_data 指向缓冲区的指针unsigned long b_rsector 实际设备上的块号.驱动机制: DMA 有时设备与系统要进行大批量的数据传输,采用中断的方式会给CPU带来很大的负荷,降低了系统的效率。 DMA操作是外设直接与内存进行数据传输,而无须CPU的干预。如硬盘数据传输、网卡数据传输等。 DMA控制器没有任何虚拟内存的概念,它只存取系统中的物理内存,不能在进程虚拟地址空间内直接使用DMA。驱动接口:设备驱动程序与外界的接口 每种类型的驱动程序,不管是字符设备还是块设备都为内核提供相同 的调用接口,因此内核能以相同的方式处理不同的设备。Linux为每 种不同类型的设备驱动程序维护相应的数据结构,以便定义统一的接 口并实现驱动程序的可装载性和动态性, Linux设备驱动程序与外界的接口分为3部分:驱动程序与内核的接口,这是通过file_operations数据结构来完成的;驱动程序与系统引导的接口,这部分利用驱动程序对设备进行初始化;设备驱动程序与设备的接口,这部分描述了驱动程序如何与设备进行交互,这与 具体设备密切相关; 它们之间的关系如下页图所示:驱动接口:驱动程序与外界的接口 设备驱动程序 操作系统内核 接口 数据结构 file_operations 实现 系统引导 接口 各设备 初始化 具体设备 接口 进行交互 驱动程序与设备间 图 设备驱动程序与外界的接口 设备驱动程序的特点(1)内核代码:设备驱动程序是内核的一部分,如果驱动程序出错,则可能导致系统崩溃。 (2)内核接口:设备驱动程序必须为内核或者其子系统提供一个标准接口。比如,一个终端 驱动程序必须为内核提供一个文件I/O接口;一个SCSI设备驱动程序应该为SCSI子系统提 供一个SCSI设备接口,同时SCSI子系统也必须为内核提供文件的I/O接口及缓冲区。 (3)内核机制和服务:设备驱动程序使用一些标准的内核服务,如内存分配等。 (4)可装载:大多数的Linux操作系统设备驱动程序都可以在需要时装载进内核,在不需要 时从内核中卸载。 (5)可设置:Linux 操作系统设备驱动程序可以集成为内核的一部分,并可以根据需要把其 中的某一部分集成到内核中,这只需要在系统编译时进行相应的设置即可。 (6)动态性:在系统启动且各个设备驱动程序初始化后,驱动程序将维护其控制的设备。如 果该设备驱动程序控制的设备不存在也不影响系统的运行,那么此时的设备驱动程序只是 多占用了一点系统内存罢了思考 设备驱动与文件的关系?提纲 设备驱动概述 如何编写内核模块 如何编写设备驱动 字符设备驱动实例内核模块在开始编写设备驱动之前,先需要了解内核模块的概念。Linux内核是一个整体的结构,因此向内核添加任何东西或者删除某些功能,都十分困难。为了解决这个问题,Linux引入了内核模块机制,从而可以动态地在内核中添加或者删除模块Linux内核中采用可加载的模块化设计 (LKMs, Loadable Kernel Modules) ,一般 情况下编译的 Linux 内核是支持可插入式模块的,也就是将最基本的核心代码编译在 内核中,其他的代码
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号