指定驱动程序加载顺序

对于大多数系统,计算机上的设备的物理层次结构决定了 Windows 和 PnP 管理器加载驱动程序的顺序。 Windows 和 PnP 管理器从系统根设备开始配置设备,然后配置根设备的子设备 (例如 PCI 适配器) 、这些设备的子设备等。 如果之前未为其他设备加载驱动程序,则 PnP 管理器在配置设备时加载每个设备的驱动程序。

INF 文件中的设置可能会影响驱动程序加载顺序。 本主题介绍供应商应在驱动程序的 INF AddService 指令引用的 service-install-节中指定的相关值。 具体而言,本主题讨论 StartTypeBootFlagsLoadOrderGroupDependencies 条目。

驱动程序应遵循以下规则来指定 StartType

  • 启动早期不需要 PnP 驱动程序

    PnP 驱动程序应具有SERVICE_DEMAND_START (0x3) 的启动类型,指定在 PnP 管理器找到驱动程序服务的设备时,PnP 管理器可以加载驱动程序。

  • 启动计算机所需的设备的驱动程序

    如果需要设备来启动计算机,则设备的驱动程序的启动类型应为 SERVICE_BOOT_START (0x0) 。

  • 启动驱动程序 ,用于检测不可 PnP 枚举的设备 ()

    对于不可 PnP 枚举的设备,驱动程序通过调用 IoReportRootDeviceIoReportDetectedDevice 将设备报告给 PnP 管理器。 此类驱动程序应具有启动类型SERVICE_SYSTEM_START (0x01) 以便 Windows 将在系统初始化期间加载驱动程序。

    只有报告非 PnP 硬件的驱动程序才应设置此启动类型。 如果驱动程序同时为 PnP 和非 PnP 设备提供服务,则应设置此启动类型。

  • 必须由服务控制管理器启动的非 PnP 驱动程序

    此类驱动程序应具有启动类型SERVICE_AUTO_START (0x02) 。 PnP 驱动程序不得设置此启动类型。

应编写 PnP 驱动程序,以便在 Windows 配置驱动程序服务的设备时加载它。 相反,在 PnP 管理器确定驱动程序服务不再存在设备时,驱动程序应能够卸载。 PnP 驱动程序应依赖的唯一驱动程序加载排序如下所示:

  1. 子设备的驱动程序可能取决于已加载父设备的驱动程序这一事实。

  2. 设备堆栈中的驱动程序可能取决于其下的任何驱动程序都加载的事实。

    例如,函数驱动程序可以确定已加载任何低筛选器驱动程序。

    但是,请注意,设备堆栈中的驱动程序不能依赖于在设备较低版本的驱动程序之后按顺序加载,因为以前在配置其他设备时可能已加载该驱动程序。

筛选器组中的筛选器驱动程序无法预测其负载顺序。 例如,如果设备有三个已注册的上层筛选器驱动程序,则这三个驱动程序都将在函数驱动程序之后加载,但可以按其上层筛选器组中的任何顺序加载。

如果驱动程序对另一个驱动程序具有显式的加载顺序依赖项,则应通过父/子关系实现该依赖项。 子设备的驱动程序可以依赖于在加载子驱动程序之前正在加载的父设备的驱动程序。

为了强调设置正确的 StartType 值的重要性,以下列表介绍了 Windows 和 PnP 管理器如何在 INF 文件中使用 StartType 条目:

  1. 在系统启动时,操作系统加载程序先加载 SERVICE_BOOT_START 类型的驱动程序,然后再将控制权转移到内核。 当内核获得控制权时,这些驱动程序位于内存中。

    启动驱动程序是在配置大多数设备之前加载的,因此无法通过设备层次结构确定其加载顺序。 启动驱动程序可以使用 INF LoadOrderGroup 条目对其加载进行排序。 操作系统忽略启动驱动程序的 INF 依赖项 条目。

  2. PnP 管理器调用SERVICE_BOOT_START驱动程序的 DriverEntry 例程,以便驱动程序可以为启动设备提供服务。

    如果启动设备具有子设备,则会枚举这些设备。 如果子设备也是启动驱动程序,则配置并启动子设备。 如果设备的驱动程序不是所有启动驱动程序,则 PnP 管理器会 (设备) 创建设备 节点 ,但尚未启动设备。

  3. 加载所有启动驱动程序并启动启动设备后,PnP 管理器将配置其余 PnP 设备并加载其驱动程序。

    PnP 管理器遍历 设备树 ,并加载尚未启动 的开发节点 的驱动程序, (即上一步) 的任何未启动开发节点。 每个设备启动时,PnP 管理器会枚举设备的子级(如果有)。

    在配置这些设备时,PnP 管理器将加载设备的驱动程序, 而不考虑 驱动程序的 StartType 值 (除非在继续启动设备之前SERVICE_DISABLED) StartType 。 其中许多驱动程序都是SERVICE_DEMAND_START驱动程序。

    对于在此步骤中加载的驱动程序,PnP 管理器会忽略由于 INF 依赖项 条目和 LoadOrderGroup 条目而创建的注册表项。 负载排序基于物理设备层次结构。

    在此步骤结束时,将配置所有设备,但不可枚举的设备以及这些设备的后代除外。 (后代可能是 PnP-enumerable.)

  4. PnP 管理器加载尚未加载的 StartType SERVICE_SYSTEM_START的驱动程序。

    这些驱动程序检测并报告其非 PnP 设备。 PnP 管理器处理这些驱动程序的 INF LoadOrderGroup 条目的结果的注册表项。 它忽略由于这些驱动程序的 INF 依赖项 条目而创建的注册表项。

  5. 服务控制管理器加载尚未加载的 StartType SERVICE_AUTO_START的驱动程序。

    服务控制管理器处理与服务的 DependOnGroupDependOnServices 相关的服务数据库信息。 此信息来自 INF AddService 条目中的依赖项条目。 请注意, 依赖项 信息仅针对非 PnP 驱动程序进行处理,因为在系统启动的早期步骤中加载了任何必需的 PnP 驱动程序。 服务控制管理器忽略 INF LoadOrderGroup 信息。

    有关服务控制管理器的详细信息,请参阅Microsoft Windows SDK文档。

使用 BootFlags 在启动时升级驱动程序的 StartType,具体取决于启动方案

操作系统可以将驱动程序的 StartType 提升为启动启动驱动程序,具体取决于驱动程序 INF 中指定的 BootFlags 值。 可以在 INF 文件中指定以下数值的一个或多个 (ORed) ,以十六进制值表示:

  • 如果应在网络启动时将驱动程序提升为启动启动驱动程序, 请指定0x1 (CM_SERVICE_NETWORK_BOOT_LOAD) 。
  • 如果在从 VHD 启动时应提升驱动程序,请指定 0x2 (CM_SERVICE_VIRTUAL_DISK_BOOT_LOAD)
  • 如果在从 USB 磁盘启动时应提升驱动程序,请指定 0x4 (CM_SERVICE_USB_DISK_BOOT_LOAD) 。
  • 如果在从 SD 存储启动时应升级驱动程序,请指定 0x8 (CM_SERVICE_SD_DISK_BOOT_LOAD)
  • 如果在从 USB 3.0 控制器上的磁盘启动时应提升驱动程序,请指定 0x10 (CM_SERVICE_USB3_DISK_BOOT_LOAD) 。
  • 如果在启用测量启动的情况下启动时应升级驱动程序, 请指定0x20 (CM_SERVICE_MEASURED_BOOT_LOAD) 。
  • 如果在启用验证程序启动的情况下启动时应升级驱动程序, 请指定0x40 (CM_SERVICE_VERIFIER_BOOT_LOAD) 。
  • 如果应在 WinPE 启动时升级驱动程序, 请指定0x80 (CM_SERVICE_WINPE_BOOT_LOAD) 。

有关在启动时提升驱动程序的 StartType 的详细信息(具体取决于启动方案),请参阅 INF AddService 指令