第 1 部分针对 Oracle Solaris 平台设计设备驱动程序
9. 直接内存访问 (Direct Memory Access, DMA)
14. 分层驱动程序接口 (Layered Driver Interface, LDI)
设备驱动程序可以正常运行后,应在分发之前全面测试该驱动程序。除了测试传统 UNIX 设备驱动程序中的功能以外,Oracle Solaris 驱动程序还需要测试电源管理功能,如驱动程序的动态装入和卸载。
驱动程序能否处理多种设备配置是测试过程的重要部分。驱动程序可以在一种简单(或缺省)配置中正常工作后,还应该测试其他配置。根据设备不同,可以通过更改跳线或 DIP 开关来完成配置测试。如果可能的配置数较少,则应尝试测试所有配置。如果可能的配置数较多,则应为这些可能的配置定义不同的类,并抽样测试每类配置。定义这些类取决于不同配置参数之间的潜在交互。这些交互是设备类型与驱动程序编写方式之间的配合。
对于每种设备配置,必须测试基本运行情况,包括装入、打开、读取、写入、关闭和卸载驱动程序。任何取决于配置的运行情况都需要特别注意。例如,更改设备寄存器的基本内存地址不可能影响大多数驱动程序函数的行为。如果驱动程序在一个地址上正常工作,则该驱动程序在其他地址上也能正常工作。另一方面,特殊 I/O 控制调用的结果可能会因特定设备配置而异。
以不同配置装入驱动程序可确保 probe(9E) 和 attach(9E) 入口点能够在不同地址找到设备。对于基本功能测试,对于字符设备,使用常规的 UNIX 命令(如 cat(1) 或 dd(1M))通常就足够了。对于块设备,可能需要挂载或引导。
对驱动程序进行全面的配置测试之后,应全面测试驱动程序的所有功能。这些测试需要执行驱动程序所有入口点的操作。
许多驱动程序需要使用定制的应用程序来测试功能。但是,对于磁盘、磁带或异步板等设备的基本驱动程序,使用标准系统实用程序即可进行测试。在此过程中,应测试所有入口点,包括 devmap(9E)、chpoll(9E) 和 ioctl(9E)(如果适用)。对于每种驱动程序,ioctl () 测试可能完全不同。对于非标准设备,通常需要使用定制的测试应用程序。
在理想环境中,驱动程序也许可以正确执行,但如果出现错误(如操作错误或数据错 误),则可能会失败。因此,驱动程序测试的一个重要部分是测试驱动程序的错误处理。
应该执行驱动程序的所有可能的错误情况,包括实际硬件故障导致的错误情况。某些硬件错误情况可能难于引发,但如有可能,应尽力强制引发或模拟此类错误。在实际使用时,所有这些情况都有可能遇到。为了测试以找出这些错误的根源,应该拆除或松开电缆、拆除板以及编写错误的用户应用程序代码。另请参见第 13 章。
注意 - 测试时,请务必采取正确的电气预防措施。 |
由于没有装入或卸载的驱动程序会导致意外的停机时间,因此必须全面测试装入和卸载。
与以下示例类似的脚本应该足够满足要求:
#!/bin/sh cd <location_of_driver> while [ 1 ] do modunload -i 'modinfo | grep " <driver_name> " | cut -cl-3' & modload <driver_name> & done
为有助于确保驱动程序正常执行,应对该驱动程序进行强有力的压力测试。例如,通过驱动程序运行单个线程并不会测试必须等待的锁定逻辑或条件变量。设备操作应由多个进程同时执行,以使几个线程同时执行同一代码。
执行同时测试的方法取决于驱动程序。某些驱动程序需要使用特殊的测试应用程序,而在后台启动多个 UNIX 命令适用于其他驱动程序。正确的测试取决于特定驱动程序在何处使用锁定和条件变量。在多处理器计算机上测试驱动程序比在单处理器计算机上测试更有可能暴露问题。
此外,还必须测试驱动程序之间的互操作性,尤其是在不同的设备可以共享中断级别的情况下。如有可能,请配置与正在测试的设备的中断级别相同的另一个设备。压力测试可以确定驱动程序是否正确请求其自己的中断,以及是否按照预期目标运行。应该对两个设备同时运行压力测试。即使设备不共享中断级别,该测试仍然很重要。例如,假设在测试某个网络驱动程序时,串行通信设备遇到错误。同一问题也可能会导致系统的其余部分遇到中断延迟问题。
这些压力测试下的驱动程序性能应使用 UNIX 性能度量工具进行度量。此类测试与使用 time(1) 命令以及压力测试所用命令一样简单。
为确保与更高发行版的兼容性以及对当前发行版的可靠支持,每个驱动程序都应该与 DDI/DKI 兼容。检查是否仅使用了《man pages section 9: DDI and DKI Kernel Functions》和《man pages section 9: DDI and DKI Driver Entry Points》中的内核例程以及《man pages section 9: DDI and DKI Properties and Data Structures》中的数据结构。
驱动程序是以软件包形式提供给客户的。可以使用某个标准机制在系统中添加或删除软件包。应对用户在系统中添加或删除软件包的能力进行测试。在测试过程中,应通过 pkg install 命令和 pkg uninstall 命令直接安装或卸载软件包。有关更多信息,请参见《添加和更新 Oracle Solaris 11.1 软件包》。
磁带机应通过执行多次归档和恢复操作来测试。cpio(1) 和 tar(1) 命令可用于此目的。使用 dd(1M) 命令可将整个磁盘分区写入磁带。接下来,读回数据,并将数据写入另一个相同大小的分区。然后比较这两个副本。mt(1) 命令可以执行特定于磁带机的大多数 I/O 控制。请参见 mtio(7I) 手册页。尝试使用所有选项。以下三种方法可以测试磁带机的错误处理能力:
移除磁带并尝试各种操作
对磁带进行写保护并尝试写入
在不同操作的执行过程中关闭电源
磁带机通常实现以独占方式访问的 open(9E) 调用。可以通过打开设备,然后让另一个进程尝试打开同一设备,来测试这些 open() 调用。
磁盘驱动程序应在原始设备模式和块设备模式下进行测试。对于块设备测试,请在设备上创建一个新的文件系统。然后,尝试挂载该新文件系统,并尝试执行多种文件操作。
注 - 文件系统使用页缓存,因此重复读取相同文件实际上并不会执行驱动程序。通过使用 mmap(2) 对文件进行内存映射,可以强制页缓存从设备中检索数据。然后使用 msync(3C) 使内存中的副本无效。
将另一个相同大小的(未挂载)分区复制到原始设备。然后使用 fsck(1M) 之类的命令检验副本的正确性。新分区也可以挂载,然后以后与旧分区进行逐文件比较。
通过为串行端口设置一个 login 连接线,可对异步驱动程序进行基本级别的测试。是否为一种较好的测试方法要看用户是否可以通过此连接线登录。但是,要充分测试异步驱动程序,必须使用多个高速中断来测试所有 I/O 控制函数。涉及回送串行电缆和较高数据传输速率的测试有助于确定驱动程序的可靠性。您可以在该连接线上运行 uucp(1C),以提供某些实践。但是,由于 uucp 执行其自己的错误处理,因此请确认驱动程序不会向 uucp 进程报告过多的错误。
这些类型的设备通常是基于 STREAMS 的。有关更多信息,请参见《STREAMS Programming Guide》。
可以使用标准网络实用程序对网络驱动程序进行测试。由于可在网络的每个端点上比较文件,因此 ftp(1) 和 rcp(1) 命令非常有用。该驱动程序应在网络负载较重的情况下测试,以便多个进程可以运行各种命令。
网络负载较重包括以下情况:
测试计算机的通信流量较大。
网络上所有计算机之间的通信流量较大。
执行测试时,应拔下网络电缆,以确保驱动程序可从产生的错误情况中正常恢复。另一项重要测试是让驱动程序快速连续接收多个包,即背对背包。在这种情况下,负载较轻的网络上相对较快的主机应向测试计算机快速连续发送多个包。请检验接收驱动程序不会丢弃第二个以及后续的包。
这些类型的设备通常是基于 STREAMS 的。有关更多信息,请参见《STREAMS Programming Guide》。
支持 SR-IOV 的驱动程序需要进行额外测试。还需要进行标准裸机测试,可以使用用于裸机测试的实用程序,如用于网络设备的 ftp 和 rcp。
有关 SR-IOV 驱动程序的信息,请参见第 21 章。
使用以下命令来测试虚拟功能 (Virtual Function, VF) 的状态:
已启用 VF-hotplug install
已禁用 VF-hotplug uninstall
已指定 VF-hotplug list
在 SPARC 系统上测试 VF 的状态时,除 hotplug 命令之外,还请使用 ldm(1M) 命令。
在各种虚拟化配置中测试 SR-IOV 设备也很重要。在 SPARC 和 x86 平台上测试 SR-IOV 驱动程序时,请尝试以下选项:
请勿配置任何虚拟功能 (Virtual Function, VF)
仅配置一个 VF
以 2 的幂次方增加配置的 VF,直到达到 VF 的最大数目
在 SPARC 平台上,使用不同数目的 IO 域并在这些域中使用不同的 VF 分布来测试功能。尝试以下配置:
将单个 VF 指定给单个 IO 域
将 2 的幂次方个 VF(可至最大值)指定给单个 IO 域
创建 2、4 或 8 个 IO 域并将不同数目的 VF 指定给每个域
将一些 VF 指定给根域并将一些 VF 指定给 IO 域
如果设备或平台支持以下功能,请对其进行测试:
从 VF 引导 IO 域
以物理形式热插入或拔出 SR-IOV 卡
在 SR-IOV 卡上执行动态重新配置操作
如果 Oracle Solaris 的多个版本都支持您的设备,对于某些测试,可通过在根域和 IO 域间混用 OS 版本来执行最终测试。