zoukankan      html  css  js  c++  java
  • 12. I/O体系结构及设备驱动 20100228 16:50 350人阅读 评论(0) 收藏

     1.       I/O体系结构

    CPU、内存、外设通过总线(BUS)传送数据,一台机器包含不同类型的总线,如PCIUSB,它们通过叫桥的硬件设备连接。CPUI/O设备之间的数据通路称I/O总线,80x8616I/O总线,每个设备连到I/O总线上,这种连接分为三个层次:

    l         I/O端口:因为I/O总线16位,所以有65535个“地址”可寻,称之为I/O端口(port),即655358I/Oport。有4inoutinsouts对相应的端口进行数据传送。端口地址可映射到物理地址空间,这样就可用mov等指令操作,且可结合DMA。在设备上,端口被组织成一组寄存器,对设备的inout就是向设备的寄存器中写值。显然,难点不在读写端口,而在于端口的分配,因为向已分配的端口瞎写会崩溃。Linux内核用叫资源(source)的资源来管理,将端口组织为树状资源,方便分配。

    l         向端口写完后,设备仍无法工作,因为设备控制器不知道寄存器中的是何数据,这时一种叫做“I/O接口”的硬件电路会将寄存器中的数据翻译成设备控制器能理解的命令与数据,I/O接口也可通过IRQ线连于可编程中断控制器上。I/O接口分:a.专用接口:控制器与接口在一起,常见的键盘接口连在键盘控制器上,后者包括一个单片机,当按键时,控制器通过接口产生中断,并将内容翻译后写到输入寄存器等CPU读端口。其余还有显卡接口、磁盘接口、网络接口等。b.通用接口:并口、串口、USB接口。串口包括一个通用异步收发器(UART)芯片,将送入端口的字节拆成位序列送设备。

    l         接口完成翻译端口数据后,设备控制器接收指令,让设备按需进行动作或将设备动作解释为命令送寄存器。比较简单的设备无设备控制器。

    2.       设备驱动程序模型

    早期,内核为写驱动的人提供如下服务:分配动态内存、保留I/O地址范围或IRQ、激活中断服务来响应中断。现在由于PCI这样的总线类型对硬件内部设计提出以下常用要求:电源管理、即插即用、热插拔,所以Linux2.6为系统中总线、设备、设备驱动提供了统一框架,称设备驱动程序模型,它的核心数据结构为kobject结构,为了与VFS保持统一,引入了sysfs文件系统在/sys/下描述外设,并与kobject对应。同类型的kobject串成链表放置在kset中,kset中有kobject类型字段给链表中元素共享,另外,kset也不独立存在,而是依托于嵌在内部的另一个kobject。这样就形成了一个树形集合,kset也有更高层的集合subsystem

    设备驱动程序模型中的每个设备由一个device对象描述,在/sys/devices下的目录对应的子系统devices_subsys中收集所有的device对象。设备按层次组织,使目录结构与真实物理设备的“父子”关系相匹配。每个设备驱动程序保持一个device对象链表,而device对象的driver字段指向设备驱动程序对象。对任一总线类型,也有一个链表将此总线上的所有设备链起,同样,device对象的bus字段回指总线描述符符。驱动程序模型中的每个驱动都用device_driver对象描述,它的关键4个方法处理热插拔、即插即用、电源管理。总线由bus_type对象描述。这里的三个对象中,前两对象有kobject成员,后一个有一个subsystem及对应前两个的kset。就是这样将通用的模型与具体的设备、驱动、总线联系起来。

    3.       设备文件

    unixOS都基于文件的概念,所以I/O设备也当作一种特殊的文件,叫设备文件,它一般位于/dev目录下,它与硬件设备或者逻辑分区对应。设备文件分两类:块、字符。而对应的硬件设备的区别大致是数据可否随机访问,字符设备要不就不可随机访问,要不就与设备位置相关(磁带)。例外的是网卡,它不与设备文件相对应。设备文件是存放于文件系统中的文件,但它的inode不指向磁盘上的数据块指针而是包含硬件设备的标志符以指出它对应字符或是块设备文件。除了这个标志,标志符还有一对参数指出主、次设备号。标志及主设备号相同的设备由同一设备驱动程序处理,次设备号则标志设备组中的某设备,从内核角度,设备文件名无关紧要,它关心的是类型、主次设备号;而对应用程序,就通过设备文件名与设备交互。传统unix中,主次设备号各8位,且设备文件被分配一次目录永久存于/dev,不够用。Linux将主加到12位,次加到20位。合并于dev_t变量。但现今常用的是动态处理设备文件,用一个udev的程序来实现动态分配设备号。设备文件的引入最终还是为与VFS接口,VFS将对设备文件的系统调用换为与设备相关的函数调用。

    4.       设备驱动程序

    上述VFS对设备文件的系统调用处理的真实实现由设备驱动程序全权负责。使用它之前,必须先注册,注册就是指分配一个device_driver对象,并插入设备驱动程序模型的数据结构中,与设备文件连接。当静态编译内核时,注册在内核初始化时完成。若作为一个内核模块编译,则在装入模块时注册。注册后,用户态应用程序可通过设备文件使用了,在使用前,要进行初始化,即分配相关资源。设备驱动程序中,I/O操作的时间是未知的,在启动I/O前,设备驱动程序必须依靠某种手段监控I/O操作是否超时等。最简单的方法是轮询,更好的是由I/O控制器通过IRQ发中断,即发出读命令后将自身阻塞,完成I/O时从中断处理程序(也由设备驱动程序提供)中读取数据,放于关于该驱动程序的全局变量中,唤醒被阻塞进程。再将数据送回应用程序。

           对于I/O映射存储器的情况,设备驱动程序必须把其物理地址转换为内核空间的线性地址。ISA总线上的大多设备被映射到0xa0000~0xfffff16位物理地址范围,这就是在640K

    ~1M中的那个空间。而PCI总线上的设备可映射到4G的物理地址范围。

           说到外设就不得不提DMA,它是用于RAMI/O设备间的传送数据的电路。按由进程还是由外设触发分为同步异步。同步如声卡,应用程序将声音数据写入设备文件,驱动程序将写入的数据存于内核缓冲区,并命令声卡将它们从中拷到DSP中,完成后来一中断。异步DMA如网卡,它从LAN中收到的帧先存在自己的I/O映射的存储器中,再发中断,驱动程序确认中断,让网卡将帧从I/O映射的存储器中拷贝到内核缓冲区中,发中断报告完成。驱动程序负责将此新帧通知给上层内核层。之前说了三种地址,其实还有第4种地址:总线地址。它是由除了CPu外的其它设备使用的存储器地址。如DMA时,它要知道内存缓冲区的地址。80x86中,总线地址与物理地址一致,但其它体系结构中,物理地址到总线地址还有一层类似分页的映射。ISA的总线地址是24位,所以DMA只用于底16MBDMA处理时,也要考虑硬件高速缓存,80x86中,硬件设备驱动程序会窥探它,所以没问题,但其它可能存在一致性问题。

           Linux内核不完全支持可能存在的I/O设备,它可能:

    1)        根本不支持,只能inout与端**流。这种情况与内核设备驱动程序毫无关系。

    2)        最小支持,不识设备,但识别接口,内核通过提供设备文件及驱动程序来处理I/O接口,通用接口只有串、并口是此类。

    3)        扩展支持:内核识别硬件设备,除串并口的所有通用接口都属此类。

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    centos6.5 mysql配置整理
    第四章 Web表单
    第三章 模板
    第二章 程序的基本结构
    第一章 安装
    常见网络错误代码(转)
    微软消息队列MessageQueue(MQ)
    基于.NET平台常用的框架整理(转)
    Sqlserver更新数据表xml类型字段内容某个节点值的脚本
    正则表达式_基础知识集合
  • 原文地址:https://www.cnblogs.com/qqmomery/p/4700460.html
Copyright © 2011-2022 走看看