Linuxオペレーティングシステムで仮想アドレスから物理アドレスを決定するためのAPIはありますか?
カーネルおよびユーザー空間は、メモリ管理ハードウェアによって物理アドレスにマップされる仮想アドレス(リニアアドレスとも呼ばれます)で機能します。このマッピングは、オペレーティングシステムによって設定されるページテーブルによって定義されます。
DMAデバイスはバスアドレスを使用します。 i386 PCでは、バスアドレスは物理アドレスと同じですが、他のアーキテクチャには、バスアドレスを物理アドレスに変換する特別なアドレスマッピングハードウェアがある場合があります。
Linuxでは、asm/io.h
から次の関数を使用できます。
これはすべて、通常のメモリへのアクセスに関するものです。 PCIまたはISAバス上に「共有メモリ」もあります。これは、ioremap()を使用して32ビットアドレス空間内にマップし、readb()、writeb( )(など)関数。
さまざまなキャッシュが存在するため、同じ物理アドレスに異なる方法でアクセスしても同じ結果が得られるとは限らないため、生活は複雑です。
また、仮想アドレスの背後にある実際の物理アドレスは変更される可能性があります。それ以上に、そのメモリにアクセスするまで、仮想アドレスに関連付けられたアドレスはありません。
ユーザーランドAPIについては、私が気づいているものはありません。
前に回答したように、通常のプログラムは便利な仮想アドレス空間で実行されるため、物理アドレスを気にする必要はありません。さらに、すべての仮想アドレスに物理アドレスがあるわけではなく、マップされたファイルまたはスワップされたページに属している場合があります。ただし、ユーザーランドであっても、このマッピングを見るのが興味深い場合があります。
この目的のために、Linuxカーネルは/proc
内の一連のファイルを介してマッピングをユーザーランドに公開します。ドキュメントは here にあります。短い要約:
/proc/$pid/maps
は、仮想アドレスのマッピングのリストと、マップされたファイルに対応するファイルなどの追加情報を提供します。/proc/$pid/pagemap
は、物理アドレスが存在する場合はそれを含む、各マップページに関する詳細情報を提供します。このWebサイト は、このインターフェイスを使用して実行中のすべてのプロセスのマッピングをダンプするCプログラムと、その機能の説明を提供します。
上記の推奨Cプログラムは通常は機能しますが、誤解を招く結果を(少なくとも)2つの方法で返す可能性があります。
一番下の行は、より信頼できる結果を確実にするためです:読み取り専用マッピングの場合、PFNをクエリする前に、すべてのページから少なくとも1回は読み取ります。書き込み可能なページの場合、PFNをクエリする前に、少なくとも1回はすべてのページに書き込みます。
もちろん、理論的には、「安定した」PFNを取得した後でも、実行時にマッピングが常に任意に変更される可能性があり(たとえば、ページをスワップに入れたりスワップしたりするとき)、依存するべきではありません。
なぜユーザーランドAPIがないのかしら。
ユーザーランドメモリの物理アドレスが不明だからです。
Linuxは、ユーザーランドメモリにデマンドページングを使用します。ユーザーの土地オブジェクトは、アクセスされるまで物理メモリを持ちません。システムのメモリが不足すると、ページがプロセスに対してロックされていないと、ユーザーランドオブジェクトがスワップアウトされ、物理メモリが失われる可能性があります。オブジェクトに再度アクセスすると、オブジェクトはスワップインされて物理メモリが与えられますが、以前の物理メモリとは異なる可能性があります。ページマッピングのスナップショットを撮ることができますが、次の瞬間に同じであるとは限りません。
したがって、ユーザーの土地オブジェクトの物理アドレスを検索しても、通常は意味がありません。