SCIENCE PARK

デバドラ講座

【 デバドラ講座12 : メモリ管理 】

1.PagedPoolとNonPagedPool

ドライバのメモリ管理は重要かつ複雑で、システムクラッシュの原因になるので、メモリを扱う際には十分に注意する必要があります。Windowsのメモリは仮想メモリ構造です。32bitOSの場合、データにアクセスするためには、2の32乗、つまり4GBのアドレス空間が必要です。64bitOSの場合、単純に考えると、2の64乗、16EBのアドレス空間が必要になりそうですが、実は64bitOSは48bit分(2の48乗=256TB)しかデータを使用しておらず、使用しないメモリ空間が存在します。

通常のメモリだけでは必要なメモリ空間容量に足りなくても、仮想メモリの概念によりメモリ存在するように処理することができます。デバイスドライバからのメモリへのアクセスは全て仮想アドレスを使います。図1はWindowsの仮想アドレスの構造を表しています。

図1:Windowsの仮想アドレスの構造
図1:Windowsの仮想アドレスの構造

メモリの使い方によってプライベート空間と共有空間の2種類のメモリがあります。ユーザーモードのアプリケーションはプライベート空間を使用します。カーネルモードのプロセスは共有空間を利用します。

Windowsでは、ページプールメモリと非ページプールメモリの2つのメモリを管理しています。ページプールメモリはページインとページアウトを利用してメモリを使用することで、使用していないページは他のページのために空けることが出来ます。ページインとは仮想メモリから1ページのメモリを物理メモリに読み込むことを指します(図2)。ページアウトとは、物理メモリから1ページのメモリを仮想メモリに戻すことを指します。先ほど、物理メモリは仮想メモリよりもはるかに小さいと説明しました。それが可能なのは、ページングのおかげとも言えます。物理メモリで不必要になったページをページアウトします。すると、それまで使用していた物理メモリ空間を他の目的のために割り当てることができます。また、ページアウトした内容が再び必要になった場合は、ページインします。

図2:ページング
図2:ページング

非ページプールメモリは変換を行わずに物理メモリから仮想メモリにそのままマップします。非ページプールメモリはページングを行わないので、必要なメモリの容量が物理メモリに存在する必要があります。物理メモリは貴重な資源なので、使用する際は慎重にならなければなりません。OSのページングを実行するコードなどの特定な主要部分も非ページプールメモリに存在します。また、非ページプールメモリはページングを行わないので、ページフォルトも発生しません。

ユーザー空間はユーザーアプリケーションが自由に使える空間です。ユーザー空間は完全にページングすることが可能です。ユーザー空間の真上にある共有空間はカーネルモードが使用します。この空間にはNT Executiveサービス、カーネル、HAL、そしてシステムデバイスドライバが割り当てられます。システムデバイスドライバとは、システムを起動するドライバです。

デバイスドライバは共有空間内にあるページプールメモリと非ページプールメモリを使用します。デバイスドライバがPASSIVE_LEVELより上位レベルのIRQLで実行するルーチンのためにメモリを確保する際、必ず非ページプールメモリを使わなければなりません。もしページプールメモリを使うと、システムがクラッシュする場合があります。ドライバはメモリを確保する際、非ページプールメモリとページプールメモリの両方から割り当てることができます。従って、メモリ割り当ては用途を考慮して行う必要があります。

参考資料

「NTドライバプログラミング」
Peter G. Viscarola、W. Anthony Mason著 久保雅俊、三浦秀朗訳 サイエンスパーク株式会社 監修
「Windows NTデバイスドライバプログラミング」
アート・ベーカー著 WinProgDDK ML和訳プロジェクト訳
「WDMデバイスドライバプログラミング完全ガイド」上
Edword N. Dekker, Jpseph M. Newcomer著 株式会社クイック訳
「WDMデバイスドライバ」
Chris Cant著 エクストランス株式会社訳 サイエンスパーク株式会社 監修
page up