驱动程序是什么
Disclaimer: 这是一篇科普文章,不会涉及太多的技术细节。
简单地说,驱动程序是操作系统与硬件(有时也包括其他的软件或在硬件上运行的firmware)之间的一种接口程序。对于操作系统来说,驱动程序是非常重要的
不过,在现代系统中,多数情况下,驱动程序并不只是简单机械地翻译操作系统的请求,更多的时候,驱动程序还有另外的很重要的作用,即绕过硬件本身的问题,常见的例如,临时加载一份较新版本的固件、针对某些版本的硬件禁用某些会导致问题的特性、分配内存的时候确保按边界对齐或只在前4GB分配以绕过DMA引擎寻址能力差的问题、通过增加延迟来解决硬件制造时对时序过于敏感的问题,等等。通过驱动程序绕过这些问题,能够让用户看不到(或者,至少在硬件负载不大的情况下看不到)问题的存在,并消除一小部分问题(例如原先随硬件发布的固件版本存在一些问题,而又没有提供更新固件的接口,新版本的驱动可能会在系统引导的过程中上传一份新版的固件到设备的临时存储)。
一般来说,驱动程序可以在逻辑上分为以下三个部分:
识别/探测部分
这一部分的主要功能,是将OS提供的一系列资源描述所对应的设备与驱动程序本身携带的识别信息,对PC而言通常是一组PCI ID进行比对;如果匹配,驱动程序将告诉操作系统自己对设备"感兴趣"。
有时,对同一个设备"感兴趣"的驱动程序可能有多个。操作系统会按照一定的规则去选择其中的一个。以 FreeBSD 为例,操作系统会根据探测函数返回的数值大小来决定最终由哪个驱动来接管设备。一些其他操作系统中,这个过程会由公共的代码以其他方式实现。
初始化部分
操作系统决定由某个具体的驱动接管设备之后,就调用驱动程序的初始化方法。驱动程序需要完成这么几个工作:
对硬件进行初始化。每个设备可能会有不同的初始化方法,这部分可能还需要担负更新固件、对设备进行一些设置等工作。此外,在这个阶段驱动程序也会从硬件中提取一些信息,例如其具体型号(特别是控制芯片的revision信息)等等。驱动程序还需要记录硬件对应的workaround信息,以备后续使用,并启用需要的workaround。
分配资源。包括用于进行DMA操作的描述符、缓冲区、中断,以及挂接在时钟处理程序上的一些定时处理程序。一些高吞吐量的设备,如网卡,可能会在这个阶段建立一系列工作线程。
通知操作系统和用户。例如,在控制台或日志中写入相关信息。这部分主要是便于查找问题。
操作翻译部分
这部分比较简单。一般来说,多数常见的硬件,如网卡、SCSI/SAS适配器、显卡等,都有与之对应的框架,而驱动程序要做的只是实现具体的方法。