次の方法で共有


Bus-Relative アドレスと仮想アドレスのマッピング

プロセッサによっては個別のメモリと I/O アドレス空間を実装するプロセッサもあれば、実装していないプロセッサもあります。 これらのハードウェア プラットフォームの違いにより、I/O またはメモリ常駐デバイス リソースへのアクセスにドライバーが使用するメカニズムは、プラットフォームによって異なります。

ドライバーは、PnP マネージャーの IRP_MN_QUERY_RESOURCE_REQUIREMENTS IRP に応答してデバイス I/O とメモリ リソースを要求します。 ハードウェア アーキテクチャに応じて、HAL は I/O 領域またはメモリ領域に I/O リソースを割り当てることができ、I/O 領域またはメモリ領域にメモリ リソースを割り当てることができます。

HAL がバス相対メモリ領域を使用してデバイス リソース (デバイス レジスタなど) にアクセスする場合、ドライバーは、これらのリソースにアクセスできるように、I/O 領域を仮想メモリにマップする必要があります。 ドライバーは、デバイスの起動時に PnP マネージャーによってドライバーに渡された変換されたリソースを調べることによって、リソースが I/O またはメモリ常駐かどうかを判断できます。 HAL が I/O スペースを使用する場合、マッピングは必要ありません。

具体的には、ドライバーは、 IRP_MN_START_DEVICE 要求を受け取ると、 IrpSp->Parameters.StartDevice.AllocatedResourcesIrpSp->Parameters.StartDevice.AllocatedResourcesTranslated の構造体を調べる必要があります。これは、PnP マネージャーがデバイスに割り当てた生の (バス相対) リソースと変換されたリソースをそれぞれ記述します。 ドライバーは、デバッグの補助として、デバイス拡張機能の各リソース一覧のコピーを保存する必要があります。

リソース リストは 未加工リストの各要素が変換されたリストの同じ要素に対応する、ペアのCM_RESOURCE_LIST構造です。 たとえば、 AllocatedResources.List[0] で生の I/O ポート範囲が記述されている場合、 AllocatedResourcesTranslated.List[0] は変換後に同じ範囲を記述します。 変換された各リソースには、物理アドレスとリソースの種類が含まれます。

ドライバーに変換されたメモリ リソース (CmResourceTypeMemory) が割り当てられている場合は、 MmMapIoSpace を呼び出して、デバイス レジスタにアクセスできる仮想アドレスに物理アドレスをマップする必要があります。 ドライバーがプラットフォームに依存しない方法で動作するには、返されるすべての翻訳されたリソースを確認し、必要に応じてマップする必要があります。

カーネル モード ドライバーは、すべてのデバイス リソースへのアクセスを確保するために、IRP_MN_START_DEVICE要求に応答して次の手順を実行する必要があります

  1. IrpSp->Parameters.StartDevice.AllocatedResources をデバイス拡張機能にコピーします。

  2. IrpSp->Parameters.StartDevice.AllocatedResourcesTranslated をデバイス拡張機能にコピーします。

  3. ループ内で、 AllocatedResourcesTranslated の各記述子要素を調べます。 記述子リソースの種類が CmResourceTypeMemory の場合は、 MmMapIoSpace を呼び出し、変換されたリソースの物理アドレスと長さを渡します。

ドライバーが PnP マネージャーから IRP_MN_STOP_DEVICE または IRP_MN_REMOVE_DEVICE 要求を受け取ったら、同様のループで MmUnmapIoSpace を呼び出してマッピングを解放する必要があります。 ドライバーは、IRP_MN_START_DEVICE要求に失敗する必要がある場合は、MmUnmapIoSpace も呼び出す必要があります。

生リソースの種類は、ドライバーが呼び出す HAL アクセス ルーチン (READ_REGISTER_XXXWRITE_REGISTER_XXXREAD_PORT_XXXWRITE_PORT_XXX) を示します。 ドライバー自体がリソースを要求したか、ドライバーのライターがデバイス ハードウェアの性質を考えると、必要な種類を認識するため、ほとんどのドライバーは、これらのルーチンのどれを使用するかを判断するために生のリソースの一覧を確認する必要はありません。

I/O 領域のリソース (CmResourceTypePortCmResourceTypeInterruptCmResourceTypeDma) の場合、ドライバーは、返された物理アドレスの下位 32 ビットを使用してデバイス リソースにアクセスする必要があります。そのために、例えば HAL の読み取りおよび書き込みルーチン READ_REGISTER_XXXWRITE_REGISTER_XXXREAD_PORT_XXXWRITE_PORT_XXX を使用します。