Skip Masthead Links gceclub.sun.com.cn   » Search:    
 Java
开发者的资源中心

Sun Microsystem
 Skip to Content
 
注册成为Sun技术社区会员
注册说明 | 我的社区

Solaris 10 软件开发人员文库 >> 设备驱动教程 >> 4.  编写设备驱动程序的技巧

 

Previous上一页3.  读写内核内存中的数据

第 4 章 编写设备驱动程序的技巧

本章为编写设备驱动程序提供了一些一般准则。这些准则分为以下几个类别:

开发过程的步骤

编写设备驱动程序的一般步骤如下:

  1. 编写、编译和连接新代码。

  2. 创建必需的硬件配置文件。

    需要创建一个专用于该设备的硬件配置文件,名为 xx .conf,其中 xx 为设备的前缀。该文件用于更新 driver.conf(4) 文件。请参阅编写设备配置文件,其中描述了 dummy 例子中配置文件的创建方法。

  3. 将该驱动程序复制适当的模块目录。

  4. 使用 add_drv(1M) 安装设备驱动程序。

  5. 加载驱动程序。

  6. 测试驱动程序。

    对驱动程序要进行以下方面的严格测试:

    • 配置

    • 功能

    • 错误处理

    • 加载和卸载

    • 压力、性能和互操作性

    • DDI/DKI 遵守情况

    • 安装和封装

    其他测试是特定于驱动程序类型的。

  7. 使用 rem_drv(1M) 删除驱动程序。

    所有驱动程序最后都需要删除,因此需要确保驱动程序能够成功删除。

欲了解开发过程的详细描述,请参阅 Writing Device Drivers 中的 Driver Development Summary

设备驱动程序编码技巧

在创建新驱动程序软件时请遵循以下准则:

  • 使用基于驱动程序名的前缀来指定全局变量和函数的惟一名称。

  • 如果开发基于现有的驱动程序,则在添加驱动程序前请修改配置文件。

    利用 add_drv(1M) 命令中的 -n 选项,可以在不加载或连接驱动程序的情况下更新驱动程序系统的配置文件。

  • 使用 cmn_err() 函数而不使用 printf() 来记录驱动程序活动。

    cmn_err(9F) 函数是在控制台上显示信息的推荐方法。对于显示诸如设备注册位之类的驱动程序所使用的专用格式,与 printf(3C) 相比,该函数具有更多的功能和用途。

  • 驱动程序退出时清除分配和其他初始化活动。

    驱动程序退出时,无论是有意的还是无意的,都需要执行诸如关闭已打开的文件、释放已分配的内存、解除互斥锁和删除已创建的所有互斥之类的任务。此外,系统必须能够关闭所有的次要设备并分离驱动程序实例,即使是在硬件出现故障以后。正确的操作顺序为:反转_fini() 例程中的 _init()操作,反转 close() 例程中的 open()操作,以及反转 detach() 例程中的 attach()操作。

  • 使用 assert(9F) 来捕捉意外的出错返回。

    ASSERT() 是一个宏,它在预期为真的条件结果却为伪情况下异常终止内核执行。要启用 ASSERT(),需要在编译期间包含 sys/debug.h 头文件并指定 DEBUG 预处理程序符号。

  • 使用 mutex_owned() 验证加锁要求和编制相关文档。

    mutex_owned(9F) 函数可帮助确定当前线程是否拥有指定的互斥。要确定线程是否拥有互斥,请在 ASSERT() 内部使用 mutex_owned()

  • 使用条件编译来减轻调试工作的压力。

    Solaris 操作系统提供多种调试函数,如 assert()mutex-owned(),它们可以在编译驱动程序时通过指定 DEBUG 预处理程序符号来启用。借助条件编译,多余代码可以从生产驱动程序中删除。该方法也只可以通过使用全局变量来实现。

  • 将一个单独的驱动程序实例用于每个要控制的设备。

  • 在设备驱动程序中尽可能多地使用 DDI 函数。

    这些接口消除了驱动程序对不同平台的依赖性,如处理器和设备字节顺序之间的不匹配以及其他的数据命令相关性。借助这些接口,单一来源的驱动程序可以运行在 SPARC 平台、x86 平台和相关的处理器架构上。

  • 预测损坏的数据。

    在使用数据前要先检查数据完整性。驱动程序必须避免将错误数据释放到系统的其他部分。

  • 设备应当只向只受控于该驱动程序的 DMA 缓冲区写入数据。

    这种方法可以防止 DMA 故障破坏系统主内存的任意部分。

  • 需要进行 DMA 传输时使用 ddi_umem_alloc(9F) 函数。

    该函数可保证只传输已调整的完整页面。

  • 在采取备用措施以处理经常性的中断之前,设置固定数量的尝试。

    如果设备加了锁,设备驱动程序不可以无限制地消耗系统资源。如果设备总是忙,则驱动程序应该是超时了。驱动程序还应检测经常性的中断请求并采取适当措施。

  • 在设置互斥获得与解除时要小心,以避免设备出现故障时不必要的线程交互。

    请参阅Writing Device Drivers 中的 Thread Interaction,了解更多信息。

  • 检查来自用户应用程序的异常 ioctl() 请求。

    用户请求可能会有潜在和有意的破坏性。驱动程序的设计应考虑到每种类型潜在 ioctl() 请求的构造。

  • 要设法避免驱动程序仍在继续运行却不检测设备故障的情况发生。

    某一驱动程序应切换到备用设备,不应一味地处理设备故障。

  • Solaris 操作系统中的所有设备驱动程序都必须支持热插拔。

    所有设备都要能够在不重启系统的情况下安装或删除。

  • 所有设备驱动程序都应支持电源管理。

    电源管理提供了控制和管理计算机系统或设备的电能使用的能力。通过在空闲时减少电能消耗以及在不使用时完全切断电源,电源管理使系统能够节省能源。

  • volatile 关键字应用于引用了设备寄存器的任何变量。

    若不带 volatile 关键字,编译时优化器可能会删除对寄存器的重要访问。

  • 执行定期的状况检查以检测和报告有故障的设备。

    定期的状况检查应包括下列活动:

    • 检查设备上所有的寄存器或存储单元,它们的值自最后一次轮询以来可能已经改变了。

    • 时间戳传出请求,如驱动程序发出的发送块或命令。

    • 在设备上启动一个应在计划的下一次检查之前完成的测试。

设备驱动程序测试技巧

测试新设备驱动程序可能会对内核产生无法挽救的破坏。下列技巧有助于避免一些重大问题:

  • 从一个单独的主系统使用串行连接来控制测试机器。

    Writing Device Drivers 中的 Testing With a Serial Connection 中介绍了该技巧。

  • 使用备用内核。

    从内核和相关的二进制文件的一个副本启动,而不从默认的内核启动,以避免意外启动系统和造成无法挽救的后果。

  • 使用辅助内核模块来测试不同的内核变量设置。

    该方法将试验与内核变量设置隔离开来。请参阅 Writing Device Drivers 中的 Avoiding Data Loss on a Test System

  • 为测试系统上可能的数据丢失制定应变计划。

    如果将测试系统设置为服务器的客户端,在出现问题时则可以从网络进行引导。也可以创建一个专用分区,供可引导的根文件系统副本使用。请参阅 Writing Device Drivers 中的 Avoiding Data Loss on a Test System

  • 如果测试系统出现忙乱,请使用系统故障转储。

  • 如果系统在 attach(9E) 过程中崩溃,请使用 fsck(1M) 来临时修复损坏的根文件系统,以便能够挽救所有故障转储。请参阅 Writing Device Drivers 中的 Recovering the Device Directory

  • 将驱动程序安装在 /tmp 目录,直到完成对 _info()_init()attach() 例程的修改和测试为止。

    将驱动程序保存在 /tmp 目录中,直到测试好驱动程序为止。如果出现忙乱,驱动程序将从 /tmp 目录中删除,且系统将成功重启。

设备驱动程序调试和优化技巧

Solaris 操作系统为调试和调优设备驱动程序提供了多种工具:

  • 使用 kmdb(1) 内核调试器进行运行时调试。

    kmdb 调试程序提供了典型的运行时调试功能,如断点、监视点和单步执行。欲了解更多信息,请参阅 Solaris Modular Debugger Guide

  • 使用 mdb(1) 模块化调试程序进行事后调试。

    事后调试在系统故障转储上执行,不在正常运行的系统上执行。借助事后调试,不同的人或过程可以同时分析相同的故障转储。此外,借助 mdb,可以创建名为 dmods 的专用宏在该转储上执行严格的分析。欲了解更多信息,请参阅 Solaris Modular Debugger Guide

  • 使用 kstat(3KSTAT) 可以为设备驱动程序输出特定于模块的内核统计数据。

  • 使用 DTrace 可以向驱动程序动态添加工具,以便执行系统分析和性能测定之类的任务。欲了解 DTrace,请参阅 Solaris Dynamic Tracing Guide

 





SUN 全 球 资 源
www.sun.com
Sun全球网站
cn.sun.com
Sun中国网站
docs.sun.com
Sun产品文档
developers.sun.com
Sun开发者资源
wwws.sun.com
Sun软件产品
www.sun.com/bigadmin/
系统管理员