DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 1260|回复: 0
打印 上一主题 下一主题

[待整理] 嵌入式Linux设备驱动开发之:设备驱动概述

[复制链接]
跳转到指定楼层
楼主
发表于 2014-10-10 07:33:17 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
        11.1  设备驱动概述

        11.1.1  设备驱动简介及驱动模块

        操作系统是通过各种驱动程序来驾驭硬件设备的,它为用户屏蔽了各种各样的设备,驱动硬件是操作系统最基本的功能,并且提供统一的操作方式。设备驱动程序是内核的一部分,硬件驱动程序是操作系统最基本的组成部分,在Linux内核源程序中也占有60%以上。因此,熟悉驱动的编写是很重要的。
         
        在第2章中已经提到过,Linux内核中采用可加载的模块化设计(LKMs,Loadable Kernel Modules),一般情况下编译的Linux内核是支持可插入式模块的,也就是将最基本的核心代码编译在内核中,其他的代码可以编译到内核中,或者编译为内核的模块文件(在需要时动态加载)。
         
        常见的驱动程序是作为内核模块动态加载的,比如声卡驱动和网卡驱动等,而Linux最基础的驱动,如CPU、PCI总线、TCP/IP协议、APM(高级电源管理)、VFS等驱动程序则直接编译在内核文件中。有时也把内核模块叫做驱动程序,只不过驱动的内容不一定是硬件罢了,比如ext3文件系统的驱动。因此,加载驱动就是加载内核模块。
         
        这里,首先列举一些模块相关的命令。
        n lsmod列出当前系统中加载的模块,其中左边第一列是模块名,第二列是该模块大小,第三列则是使用该模块的对象数目。如下所示:
         
        $ lsmod      
        Module               Size    Used by   
        Autofs               12068   0  (autoclean) (unused)
        eepro100            18128   1
        iptable_nat         19252   0  (autoclean) (unused)
        ip_conntrack       18540   1  (autoclean) [iptable_nat]
        iptable_mangle     2272    0  (autoclean) (unused)
        iptable_filter     2272    0  (autoclean) (unused)
        ip_tables           11936   5  [iptable_nat iptable_mangle iptable_filter]
        usb-ohci            19328   0  (unused)
        usbcore             54528   1  [usb-ohci]
        ext3                 67728   2
        jbd                  44480   2  [ext3]
        aic7xxx             114704  3
        sd_mod              11584   3
        scsi_mod           98512   2  [aic7xxx sd_mod]
         
        n rmmod是用于将当前模块卸载。
        n insmod和modprobe是用于加载当前模块,但insmod不会自动解决依存关系,即如果要加载的模块引用了当前内核符号表中不存在的符号,则无法加载,也不会去查在其他尚未加载的模块中是否定义了该符号;modprobe可以根据模块间依存关系以及/etc/modules.conf文件中的内容自动加载其他有依赖关系的模块。
         
        11.1.2  设备分类

        本书在前面也提到过,Linux的一个重要特点就是将所有的设备都当做文件进行处理,这一类特殊文件就是设备文件,它们可以使用前面提到的文件、I/O相关函数进行操作,这样就大大方便了对设备的处理。它通常在/dev下面存在一个对应的逻辑设备节点,这个节点以文件的形式存在。
         
        Linux系统的设备分为3类:字符设备、块设备和网络设备。
         
        n 字符设备通常指像普通文件或字节流一样,以字节为单位顺序读写的设备, 如并口设备、虚拟控制台等。字符设备可以通过设备文件节点访问,它与普通文件之间的区别在于普通文件可以被随机访问(可以前后移动访问指针),而大多数字符设备只能提供顺序访问,因为对它们的访问不会被系统所缓存。但也有例外,例如帧缓存(framebuffer)是一个可以被随机访问的字符设备。
         
        n 块设备通常指一些需要以块为单位随机读写的设备,如IDE硬盘、SCSI硬盘、光驱等。块设备也是通过文件节点来访问,它不仅可以提供随机访问,而且可以容纳文件系统(例如硬盘、闪存等)。Linux可以使用户态程序像访问字符设备一样每次进行任意字节的操作,只是在内核态内部中的管理方式和内核提供的驱动接口上不同。
         
        通过文件属性可以查看它们是哪种设备文件(字符设备文件或块设备文件)。
         
        $ ls –l /dev
        crw-rw----  1 root  uucp 4,  64 08-30 22:58 ttyS0 /*串口设备, c表示字符设备*/
        brw-r-----  1 root  floppy 2,   0 08-30 22:58 fd0/*软盘设备,b表示块设备*/
         
        n 网络设备通常是指通过网络能够与其他主机进行数据通信的设备,如网卡等。
         
        内核和网络设备驱动程序之间的通信调用一套数据包处理函数,它们完全不同于内核和字符以及块设备驱动程序之间的通信(read()、write()等函数)。Linux网络设备不是面向流的设备,因此不会将网络设备的名字(例如eth0)映射到文件系统中去。
         
        对这3种设备文件编写驱动程序时会有一定的区别,本书在后面会有相关内容的讲解。
         
        11.1.3  设备号

        设备号是一个数字,它是设备的标志。就如前面所述,一个设备文件(也就是设备节点)可以通过mknod命令来创建,其中指定了主设备号和次设备号。主设备号表明设备的类型(例如串口设备、SCSI硬盘),与一个确定的驱动程序对应;次设备号通常是用于标明不同的属性,例如不同的使用方法、不同的位置、不同的操作等,它标志着某个具体的物理设备。高字节为主设备号,底字节为次设备号。
         
        例如,在系统中的块设备IDE硬盘的主设备号是3,而多个IDE硬盘及其各个分区分别赋予次设备号1、2、3…
         
        $ ls –l /dev
        crw-rw----  1 root  uucp 4,  64 08-30 22:58 ttyS0 /* 主设备号4,此设备号64 */
         
        11.1.4  驱动层次结构

        Linux下的设备驱动程序是内核的一部分,运行在内核模式下,也就是说设备驱动程序为内核提供了一个I/O接口,用户使用这个接口实现对设备的操作。图11.1显示了典型的Linux输入/输出系统中各层次结构和功能。
       

        图11.1  Linux输入/输出系统

       
        层次结构和功能
        Linux设备驱动程序包含中断处理程序和设备服务子程序两部分。
         
        设备服务子程序包含了所有与设备操作相关的处理代码。它从面向用户进程的设备文件系统中接受用户命令,并对设备控制器执行操作。这样,设备驱动程序屏蔽了设备的特殊性,使用户可以像对待文件一样操作设备。
         
        设备控制器获得系统服务有两种方式:查询和中断。因为Linux的设备驱动程序是内核的一部分,在设备查询期间系统不能运行其他代码,查询方式的工作效率比较低,所以只有少数设备如软盘驱动程序采取这种方式,大多设备以中断方式向设备驱动程序发出输入/输出请求。
         
        11.1.5  设备驱动程序与外界的接口

        每种类型的驱动程序,不管是字符设备还是块设备都为内核提供相同的调用接口,因此内核能以相同的方式处理不同的设备。Linux为每种不同类型的设备驱动程序维护相应的数据结构,以便定义统一的接口并实现驱动程序的可装载性和动态性。Linux设备驱动程序与外界的接口可以分为如下3个部分。
         
        n 驱动程序与操作系统内核的接口:这是通过数据结构file_operations(在本书后面会有详细介绍)来完成的。
        n 驱动程序与系统引导的接口:这部分利用驱动程序对设备进行初始化。
        n 驱动程序与设备的接口:这部分描述了驱动程序如何与设备进行交互,这与具体设备密切相关。
        它们之间的相互关系如图11.2所示。
       

        图11.2  设备驱动程序与外界的接口

         
        11.1.6  设备驱动程序的特点

         
        综上所述,Linux中的设备驱动程序有如下特点。
        (1)内核代码:设备驱动程序是内核的一部分,如果驱动程序出错,则可能导致系统崩溃。
         
        (2)内核接口:设备驱动程序必须为内核或者其子系统提供一个标准接口。比如,一个终端驱动程序必须为内核提供一个文件I/O接口;一个SCSI设备驱动程序应该为SCSI子系统提供一个SCSI设备接口,同时SCSI子系统也必须为内核提供文件的I/O接口及缓冲区。
         
        (3)内核机制和服务:设备驱动程序使用一些标准的内核服务,如内存分配等。
         
        (4)可装载:大多数的Linux操作系统设备驱动程序都可以在需要时装载进内核,在不需要时从内核中卸载。
         
        (5)可设置:Linux操作系统设备驱动程序可以集成为内核的一部分,并可以根据需要把其中的某一部分集成到内核中,这只需要在系统编译时进行相应的设置即可。
         
        (6)动态性:在系统启动且各个设备驱动程序初始化后,驱动程序将维护其控制的设备。如果该设备驱动程序控制的设备不存在也不影响系统的运行,那么此时的设备驱动程序只是多占用了一点系统内存罢了。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2024-11-15 02:12 , 耗时 0.083974 秒, 21 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表