编写设备驱动程序

检测已损坏的数据

以下各节介绍可能发生数据损坏的位置以及如何检测损坏。

设备管理和控制数据的损坏

驱动程序应假定,从设备获取的任何数据(无论通过 PIO 还是 DMA)都可能已被损坏。需要特别指出的是,对于基于设备数据的指针、内存偏移以及数组索引要格外小心。此类值可以是恶性的,因为取消引用这些值时会导致内核出现紧急情况。在使用之前,应针对所有此类值执行范围和对齐检查(如果需要)。

即使是非恶性指针,仍然可能具有误导性。例如,指针可能指向某个对象的有效但错误的实例。驱动程序应尽量交叉检查指针以及该指针所指向的对象,或者对通过该指针获得的数据进行验证。

其他类型的数据也可能具有误导性,如包长度、状态字或通道 ID。应尽可能地对这些数据类型进行检查。可对包长度进行范围检查,以确保该长度既不为负,也不比包含缓冲区大。可针对“不可能”的位对状态字进行检查。可将通道 ID 与有效 ID 的列表进行匹配。

其中,一个值标识一个流,驱动程序必须确保该流仍然存在。处理 STREAMS 的异步性质意味着可在设备中断仍未完成时中断流。

驱动程序不应从设备中重新读取数据。数据应只读取一次,然后进行验证并以驱动程序的本地状态进行存储。此方法可避免数据在初始读取时正确但以后重新读取时错误的风险。

驱动程序还应确保已限制所有循环。例如,返回连续 BUSY 状态的设备不能锁定整个系统。

已接收数据的损坏

设备错误可能导致将损坏的数据放置在接收缓冲区中。此类损坏与设备域之外(例如,网络中)发生的损坏几乎没有区别。通常可利用现有软件处理此类问题。例如,在协议栈的传输层进行完整性检查,或者在使用该设备的应用程序内进行完整性检查。

如果不打算在较高层对已接收的数据进行完整性检查,则可在驱动程序自身内对数据进行完整性检查。对已接收数据中的损坏进行检测的方法通常特定于设备。例如,校验和与 CRC 即是可执行的检查种类。