ほとんどのシステムでは、コンピューター上のデバイスの物理階層によって、Windowsと PnP マネージャーがドライバーを読み込む順序が決まります。 Windows および PnP マネージャーは、システム ルート デバイスから始めてデバイスを構成し、次にルート デバイスの子デバイス (たとえば PCI アダプター)、さらにそれらのデバイスの子デバイス、というように順に構成します。 PnP マネージャーは、デバイスの構成時に各デバイスのドライバーを読み込みます (ドライバーが別のデバイス用に以前に読み込まれなかった場合)。
INF ファイルの設定は、ドライバーの読み込み順序に影響を与える可能性があります。 このトピックでは、ドライバーの INF AddService ディレクティブ によって参照される service-install-section でベンダーが指定する必要がある関連する値について説明します。 具体的には、StartType、BootFlags、LoadOrderGroup、Dependencies の各エントリについて説明します。
ドライバーは、 StartType を指定するために次の規則に従う必要があります。
PnP ドライバーは起動の早い段階で必要ありません
PnP ドライバーには、ドライバーがサービスするデバイスが PnP マネージャーによって検出されたときに PnP マネージャーがドライバーを読み込むことができることを指定する、SERVICE_DEMAND_START (0x3) の開始の種類が必要です。
コンピューターの起動に必要なデバイス ドライバー
デバイスがコンピューターの起動に必要な場合、デバイスのドライバーの開始タイプは SERVICE_BOOT_START (0x0) である必要があります。
PnP 列挙可能でないデバイスを検出する非ブート開始ドライバー
PnP 列挙可能でないデバイスの場合、ドライバーは IoReportRootDevice または IoReportDetectedDevice を呼び出して PnP マネージャーにデバイスを報告します。 このようなドライバーには開始の種類は SERVICE_SYSTEM_START (0x01) である必要があるため、Windowsはシステムの初期化中にドライバーを読み込みます。
PnP 以外のハードウェアを報告するドライバーのみが、この開始タイプを設定する必要があります。 ドライバーが PnP デバイスと非 PnP デバイスの両方をサポートする場合は、この開始タイプを設定する必要があります。
サービス コントロール マネージャーによって開始される必要がある PnP 以外のドライバー
このようなドライバーには、開始の種類は SERVICE_AUTO_START (0x02) である必要があります。 PnP ドライバーでは、この開始タイプを設定しないでください。
PnP ドライバーは、Windows がそのドライバーが対応するデバイスを構成するときに読み込めるように記述する必要があります。 逆に、PnP マネージャーがそのドライバーが対応するデバイスが存在しなくなったと判断したときはいつでも、ドライバーをアンロードできる必要があります。 PnP ドライバーが依存すべき唯一のドライバーのロード順序グループは、次のとおりです。
子デバイスのドライバーは、親デバイスのドライバーが読み込まれていることに依存することがあります。
デバイス スタック内のドライバーは、その下位のドライバーが読み込まれていることを前提にできます。
たとえば、ファンクション ドライバーは、下位フィルター ドライバーが読み込まれていることを確信できます。
ただし、デバイス スタック内のドライバーは、別のデバイスが構成されたときに以前に読み込まれた可能性があるため、デバイスの下位ドライバーの後に順番に読み込まれることを当てにできないことに注意してください。
フィルター グループ内のフィルター ドライバーは、その読み込み順序を予測できません。 たとえば、デバイスに 3 つの上位フィルター ドライバーが登録されている場合、これらの 3 つのドライバーはすべて関数ドライバーの後に読み込まれますが、上位フィルター グループ内の任意の順序で読み込むことができます。
ドライバーが別のドライバーに明示的な読み込み順序の依存関係を持っている場合、その依存関係は親子関係を通じて実装する必要があります。 子デバイスのドライバーは、子ドライバーが読み込まれる前に読み込まれる親デバイスのドライバーに依存できます。
正しい StartType 値を設定することの重要性を強化するために、次の一覧では、Windowsおよび PnP マネージャーが INF ファイルの StartType エントリを使用する方法について説明します。
システムの起動時に、オペレーティング システム ローダーは、カーネルに制御を転送する前に、SERVICE_BOOT_START型のドライバーを読み込みます。 カーネルが制御を取得すると、これらのドライバーはメモリに読み込まれています。
ブートスタート ドライバーは、ほとんどのデバイスが構成される前に読み込まれるため、デバイス階層で読み込み順序を決定できません。 ブートスタート ドライバーでは、INF LoadOrderGroup エントリを使用して読み込みを並べ替えることができます。 オペレーティング システムは、ブートスタート ドライバーの INF 依存関係 エントリを無視します。
PnP マネージャーは、ドライバーがブート デバイスを処理できるように、SERVICE_BOOT_START ドライバーの DriverEntry ルーチンを呼び出します。
ブート デバイスに子デバイスがある場合は、それらのデバイスが列挙されます。 子デバイスは、ドライバーもブート開始ドライバーである場合に構成され、起動されます。 デバイスのドライバーがすべてブート開始ドライバーではない場合、PnP マネージャーはデバイスのデバイス ノード (devnode) を作成しますが、まだデバイスを起動しません。
すべてのブート ドライバーが読み込まれ、ブート デバイスが起動すると、PnP マネージャーは残りの PnP デバイスを構成し、ドライバーを読み込みます。
PnP マネージャーは 、デバイス ツリー をウォークし、まだ開始されていない devnode のドライバー (つまり、前の手順で開始されていないすべての devnode) を読み込みます。 各デバイスが起動すると、PnP マネージャーはデバイスの子 (存在する場合) を列挙します。
これらのデバイスを構成すると、PnP マネージャーは、デバイスの起動に進む前に、ドライバーの StartType 値 (StartType がSERVICE_DISABLEDされている場合を除く) に関係なく、デバイスのドライバーを読み込みます。 これらのドライバーの多くは、SERVICE_DEMAND_START ドライバーです。
PnP マネージャーは、この手順で読み込まれるドライバーの INF Dependencies エントリと LoadOrderGroup エントリの結果として作成されたレジストリ エントリを無視します。 ロード順序は、物理デバイス階層に基づいています。
この手順の最後に、PnP 列挙可能でないデバイスとそれらのデバイスの子孫を除き、すべてのデバイスが構成されます。 (子孫ノードは PnP 列挙可能な場合もあれば、そうでない場合もあります)。
PnP マネージャーは、まだ読み込まれていない StartType SERVICE_SYSTEM_STARTのドライバーを読み込みます。
これらのドライバーは、PnP 以外のデバイスを検出して報告します。 PnP マネージャーは、これらのドライバーの INF LoadOrderGroup エントリの結果であるレジストリ エントリを処理します。 これらのドライバーの INF Dependencies エントリが原因で作成されたレジストリ エントリは無視されます。
サービス コントロール マネージャーは、まだ読み込まれていない StartType が SERVICE_AUTO_START のドライバーを読み込みます。
サービス コントロール マネージャーは、サービスの DependOnGroup と DependOnServices に関するサービス データベース情報を処理します。 この情報は、INF AddService エントリの Dependencies エントリから取得されます。 依存関係情報は、必要な PnP ドライバーがシステム起動の前の手順で読み込まれたため、PnP 以外のドライバーに対してのみ処理されることに注意してください。 サービス コントロール マネージャーは、INF LoadOrderGroup 情報を無視します。
サービス コントロール マネージャーの詳細については、Microsoft Windows SDK のドキュメントを参照してください。
ブート シナリオに応じてブート時に BootFlags を使用してドライバーの StartType を昇格する
オペレーティング システムは、ドライバーの INF で指定された BootFlags 値に応じて、ドライバーの StartType を起動開始ドライバーに昇格させることができます。 INF ファイルでは、次の数値のうち、1 つ以上を OR 条件で 16 進数として指定できます。
- ネットワーク 起動時にドライバーをブート スタート ドライバーに昇格させる必要がある場合は、 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 ディレクティブを参照してください。