現在オフラインです。再接続するためにインターネットの接続を待っています

[NT DDK] プロセスアドレス空間にアダプタ RAM をマッピング

この記事は、以前は次の ID で公開されていました: JP189327
サポート期間が終了した「サポート技術情報」資料に関する免責事項
この資料は、マイクロソフトでサポートされていない製品について記述したものです。そのため、この資料は現状ベースで提供されており、今後更新されることはありません。
概要


大量のアダプタメモリをマッピングする場合に共通する問題として以下のものがあります。
  • システム PTE が利用不可能 (NO_MORE_SYSTEM_PTES)
  • 十分な連続したプロセスアドレス空間がない
この資料では、なぜこれらの問題が起こるのか、どのようにそれを回避するのかを説明しています。また、プロセスアドレス空間にアダプタメモリをマップする 2 つの方法を紹介しています。
詳細

ページテーブル エントリ (PTE) の紹介

Windows NT システムで実行されるあらゆるプロセスは、0x00000000 から 0xFFFFFFFF まで使用できる 4GB の仮想アドレス範囲を持っています。この中で、0x8000000 から 0xFFFFFFFF の上くらい 2GB のアドレス範囲は、システム内のすべてのプロセス実行に共通に使用され、これはカーネル空間またはシステムアドレス空間と呼ばれています。0x00000000 から 0x7FFFFFFF の下くらい領域範囲は、ユーザアドレス空間と呼ばれています。

プロセスから見て、仮想アドレスの各要素は 1 バイトの物理メモリを概念的に参照します。それぞれの仮想アドレスを対応する物理アドレスに翻訳 (またはマップ) するのは、プロセッサのメモリ マネージャ ユニット (MMU) と関連した仮想メモリ マネージャ( VMM )の仕事です。VMM のマッピング方法は、RAM を固定サイズのページフレームに分割し、これらのページフレームの情報を保管して、それらをマップするためのページテーブルを作成します。各 PTE はページフレームを表し、VMM がページを配置するために必要な情報を含んでいます。

4KB のページサイズを使う x86 ベースのシステムで、2GB のアドレス空間をマップするために必要な PTE の最大値は、524,288 ( 2 GB/4 KB )になります。普通のシステムでは、最大 50,000 の PTE(約 195MB のアドレス空間) が一般的な目的で予約され、残りはシステムキャッシュ、ハイパースペース、ページドプール、ノンページドプール、クラッシュダンプ領域などをマッピングするために使用されます。この PTE プールサイズは、システムの物理メモリサイズによって、システム起動時に自動的に決定されます。このプールは、ページドプールとノンページドプールから獲得され、システムの物理メモリサイズによって増減します。

システムは、カーネル スレッド スタックを生成したり、デバイスドライバやそれらの DLL をロードしたり、I/O 転送のためや MmMapIoSpace/MmMapLockedPages/MmGetSystemAddressForMdl/MmAllocateNonCachedMemory などの呼び出し側のためのシステム仮想アドレス空間をマップしたり、他のいろいろな目的でこれらの PTE を使います。このシステム PTE プールは、盛んに使用され断片化も盛んに発生します。これは、たとえ十分に大きなトータルのアドレス空間が残っていたとしても、ある時点ではドライバが十分に連続した仮想アドレス空間を獲得できないかもしれないことを意味します。また、ドライバがそれをすべて使用する場合、システムの他の部分が取り上げられ、結果的にスレッドが生成されなくなり、システムが停止し、(あるドライバが MustSucceed パラメタを設定したシステムメモリ割り当ての呼び出しによる) バグチェック メッセージが表示されてしまいます。

ドライバ作成者がこのプールを使用する時は、あるプロセスコンテキストから、システムアクセスを本当に必要とするアダプタ RAM の部分をマップして、必要な量だけをマップするということを、非常に注意しなければならないというのが結論です。システム モードからそのすべてを本当にアクセスする必要がないなら、すべてのアダプタ範囲をマップしないことです。

重要:正しいプロセスコンテキストでそれを使用したらすぐに、そのメモリをアンマップします。さもなければ、システムはすぐに PTE 不足となりバグチェックが表示されます。全システムメモリによって計算された PTE のデフォルト値は、以下のレジストリに値を追加することによって最大値を変更することができます:
  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SessionManager  \MemoryManagement\SystemPages
パフォーマンスモニタを使って、現在利用可能な「Free System Page Table Entries」をモニターできます。

以下にアダプタ RAM をマップする 2 つ方法を示します。最初の方法は、プロセスユーザアドレス空間に直接メモリをマップします。二番目の方法は、システムとユーザプロセスアドレス空間の両方にメモリをマップします。これらの方法の両方とも、物理メモリが連続していることを要求します。PTE の制限のために、システムアドレス空間に大量のメモリをマップすることができないかもしれません。しかし、メモリが断片化されず、すべてのユーザアドレス空間を使い果たさなければ、同じプロセスのユーザ空間にあるメモリのマッピングに成功するかもしれません。

セクション オブジェクト手法:

このマッピング方法を実現する方法を示すサンプル (MAPMEM) が、Windows NT 4.0 DDK(MSDN プロフェッショナルメンバシップで提供されます) にあります。
  1. アダプタ RAM の翻訳された物理アドレスを得ます (HalTranslateBusAddress)。
  2. 物理メモリデバイス \Device\PhysicalMemory に対するセクションハンドルをオープンします (ZwOpenSection)。
  3. 削除されないように、そのオブジェクトハンドルにリファレンスを付けます (ObReferenceObjectByHandle)。
  4. そのメモリをマップします (ZwMapViewOfSection)。
ZwMapViewOfSection で得た仮想アドレスは、マップしたプロセスのコンテキストの中だけに有効です。任意のプロセスコンテキストで実行するドライバの遅延手続き呼出し (DPC)、または割込みサービスルーチン (ISR) から、メモリをアクセスしたい場合は、システムアドレス空間 (次の方法を使用します) の中にそのメモリをマップしなければなりません。プロセスから終了する前に、マップされた同じプロセスコンテキストの中のメモリをアンマップしなければなりません( ZwUnMapViewOfSection )。

MmMapIoSpace 手法:

この手法は、プロセスユーザとシステムアドレス空間の両方のメモリをマップする方法を示します。
  1. アダプタ RAM の翻訳された物理アドレスを得ます (HalTranslateBusAddress)。
  2. ノンページド システムアドレス空間にメモリをマップします。
       SystemVirtualAddress = MmMapIoSpace(PhysicalAddress, SizeofRam, CacheEnable)
  3. Mdl を割り当てます。
       Mdl = IoAllocateMdl(SystemVirtualAddress, SizeOfRam, FALSE, FALSE, NULL)
  4. メモリページを記述するために Mdl を作成します。
       MmBuildMdlForNonPagedPool(Mdl)
  5. プロセスユーザアドレス空間にメモリをマップします。
       UserVirtualAddress = MmMapLockedPages(Mdl, UserMode)
この手法の利点は、DPC と ISR のようなどんなプロセスコンテキストでも使用できる SystemVirtualAddress と、ユーザ モード アプリケーションによって使用できる UserVirtualAddress を得られることです。
プロセスユーザアドレス空間にマップする場合、プロセスから終了する前に、同じプロセスコンテキストにあるマップしたメモリをアンロック( MmUnlockPages )して、アンマップ( MmUnmapIoSpace )しなければなりません。
関連情報
Windows NT 4.0 DDK ドキュメント。Helen Custer 著「INSIDE Windows NT」
関連情報
この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 189327 (最終更新日 1998-07-16) をもとに作成したものです。

MmMapIoSpace MmMapLockedPages ZwMapViewOfSection NO_MORE_SYSTEM_PTES IoFreeMdl(Mdl);
プロパティ

文書番号:189327 - 最終更新日: 07/16/1998 10:30:00 - リビジョン: 1.0

  • Microsoft Win32 Device Driver Kit for Windows NT 4.0
  • kbdsh kbinfo kbkmode kbntos400 KB189327
フィードバック