1 无线协议概述
WiFi技术经过十几年的快速发展,所支持的无线传输速率已从最初的1 Mb/s提升到1 Gb/s以上。WiFi技术主要涉及到网络协议簇的最低两层:物理层和媒体接入层,物理层采用纯硬件的实现形式,而媒体接入层则采用软硬件联合的实现方式:对于时延特性要求高的功能,采用协议硬件加速器来实现;对于网络管理等对时延要求不高的其他功能,采用驱动程序来实现。驱动在执行过程中需根据网络当前状态对硬件进行实时配置,其可靠性和稳定性直接决定了整个WiFi芯片及网络的可用性。
在驱动程序的开发中需要结合快速、有效的开发测试技术,但Linux系统在驱动开发方法和工具方面取得的进展有限,目前主要采用printk信息打印、kgdb源码调试及kdump崩溃存储技术。由于需要开发人员精通内核底层数据结构,技术门槛较高,导致只有printk打印方式得到了广泛的应用。对于非法内存访问、无效内存管理及软硬件响应不匹配等常见的无线驱动缺陷类型,当缺陷发生时会导致内核和系统的崩溃,而采用printk等技术很难查找出这些缺陷。而对于用户空间驱动程序、高层建模开发语言等新兴的驱动开发方案来说,由于尚未提供完整的驱动开发解决方案,且执行效率较低,不适合实时吞吐量大的网络驱动程序的开发。因此需要在现有驱动开发测试手段的基础上,提出新的高效的开发测试技术,以能够快速全面查找和定位驱动缺陷,提高驱动程序的可靠性和稳定性。
2 开发测试方案
无线驱动程序需要实现Linux系统对无线网络的管理接口,必须与硬件实时交互。因此,无线驱动程序的开发涉及到软硬件联合开发测试,其面临的主要问题包括:
(1)硬件不可用。由于硬件开发周期长,驱动必须能够在硬件尚不可用的情形下独立开展开发和测试。
(2)联合测试问题多且不易定位。在软硬件联合测试时,必须能够快速定位出问题的位置是位于驱动还是位于硬件部分。
(3)驱动测试手段匮乏,开发效率低。这是驱动程序开发所面临的一个共同问题,必须提出一个行之有效的驱动开发测试方案来加快驱动的开发进程。
针对上述问题,在实际的无线驱动开发过程中,本文提出了以下几种开发测试技术:
(1)精确硬件仿真。为了解决硬件尚不可用的问题,编写了可精确模拟硬件的接口及行为的内核仿真模块,提供了对硬件接口、硬件协议加速器和基带的精确模拟。具体来说,模拟的功能包括硬件中断的产生和处理、数据的发送和接收、硬件发送队列的管理,以及对硬件寄存器和存储区的模拟等。除了模拟硬件正常工作时的场景,还可以模拟硬件在实际工作中可能会产生的各种错误,进而测试软件驱动模块在硬件发生异常时的行为及稳定性,而这是在采用实际的硬件进行测试时很难做到的。通过采用精确硬件仿真技术,使得无线驱动程序代码在与实际的硬件联合测试时只需要进行少量修改,甚至不需要修改也能够正常运行。
(2)实时驱动状态控制。无线协议本质上是一个FSM有限状态机,相应的驱动程序也被设计为一个基于事件-消息驱动的系统:根据最新发生的事件或接收到的消息确定下一步的行为和状态。如果能够对驱动程序的状态进行控制,能够将驱动设置为任意的状态,就可以遍历驱动程序的状态进行测试。为了实现驱动状态控制功能,在保持驱动程序具有良好的层次结构和清晰的状态转移过程的同时,增加了驱动状态控制模块,能够按需控制和设置驱动的当前状态及所需数据。在具体实现时,该控制功能由位于用户空间的控制程序和位于内核空间的控制模块组成,采用netlink接口作为两者之间的通信接口,运行自定义的接口通信协议。在测试时,控制模块根据所接收到的控制程序的设置命令,将驱动程序配置为指定的运行状态,并全面收集驱动程序的最新事件和消息,并及时反馈给控制程序,从而实现了所需的实时驱动状态控制功能。
(3)高效用户态数据的注入和输出。在对无线驱动进行测试时,除了需要实时控制驱动程序的状态,还需要向驱动注入大量的测试数据。常规的方法是通过ioctl接口传输配置命令,通过用户空间的测试程序发送和接收待测数据包。该方法存在的问题:一是数据传输效率低,二是开发人员可控的因素较少,很难构造出复杂多变及特殊的测试数据。为了解决上述问题,本文提出了一种高效的用户态数据的注入和输出解决方案。在该方案中,由位于用户空间的测试程序产生符合各种测试需求的测试数据,通过netlink接口直接注入到位于内核空间的无线驱动程序中;由位于内核空间的测试代理模块及时收集驱动的测试结果及相关数据,并通过netlink接口直接输出到用户空间的测试程序。采用本方案,可以构造出任意格式的测试数据,覆盖各种测试功能,可以编写功能强大的用户空间分析测试程序对测试数据和结果进行分析,快速发现和定位驱动缺陷。
3 测试结果
在进行驱动开发时,为了避免由驱动缺陷导致的系统崩溃时调试信息丢失的问题,采用了双机远程开发测试方案。将被测机器(运行无线驱动程序的机器)通过有线网络连接到远程控制机器,采用这种开发配置方案,由于远程控制机器与被测机器相互独立,当驱动程序在运行过程中由于缺陷导致被测机器崩溃时,则可以在被测机器重新启动的同时,在远程控制机器上分析驱动程序输出的运行期信息和调试日志,确定系统崩溃时驱动程序的状态及相关的数据,查找出缺陷并及时更正,然后通过svn下载到被测机器运行测试,从而可以节约驱动调试时间,加快驱动缺陷修复的进度。
驱动开发过程中发现,由于涉及模块较多、软件和硬件单独开发等原因,出现了较多的软件模块间及软硬件间定义不一致的问题,这类问题以及较为普遍的空指针问题,容易导致地址非法访问而系统崩溃。这些问题均通过本文所提出的数据注入和驱动状态远程输出技术得以发现和解决,并通过实时驱动状态控制技术发现和解决了程序逻辑错误类型的缺陷。硬件本身所具有的缺陷占到了1/4以上,通过对硬件进行精确全面的仿真,驱动程序代码基本上不需要做过多的改动,即可在真正的硬件上通过测试,并在辅助硬件开发人员定性和定位硬件缺陷方面发挥了较大的作用。
在Linux驱动程序开发过程中,由于高效的开发测试手段的匮乏,使得驱动程序的开发变得缓慢和困难。本文提出了硬件仿真、状态控制和数据注入等技术,可以有效地辅助完成驱动的开发测试工作,快速高效地查找出驱动缺陷,加快驱动开发的进度,在驱动程序开发测试方面具有良好的借鉴意义。