ページテーブルの物理アドレスを取得するには?

ページテーブルの物理アドレスを取得するには?

実際の住所を見つけようとしています。ページテーブルしかし、常に失敗しました。

私が試す最後のオプションは、階層ページテーブルを作成または拡張するときにカーネルコードを変更し、単に物理アドレスを印刷することです。

しかし、ページテーブルの物理アドレスを確認する別の方法がありますか?仮想マッピングと物理マッピングを見つけるために、単に/proc/PID/pagemapを読むのと似ています。

答え1

様々な誤解。

  1. 最新のプロセッサ、特にaarch64、x86_64にはページテーブルはありません。メモリ空間にランダムに分散できる多段構造です。見つかる住所がありません!参照するアーキテクチャとレベルを指定する必要があります。
  2. 必ずしもすべてのアーキテクチャが実際に物理アドレス空間にページテーブルバージョンを持っているわけではありません。特に、組み込みプロセッサタイプにはそのための内蔵メモリがありますが、RAMにはまったくありません。繰り返しますが、参照するアーキテクチャについて具体的に説明する必要があります。
  3. すべてのオペレーティングシステムが同じように尋ねられています。しかし、Linuxがページテーブルを構築し、mmuと対話する方法は、他のUnixoidオペレーティングシステムと必ずしも同じではありません。どういう意味か具体的に説明しなければなりません!

私が試す最後のオプションは、階層ページテーブルを作成または拡張するときにカーネルコードを変更し、単に物理アドレスを印刷することです。

面白いのはそれがあなたのことだ。最後オプション!ユーザー空間、つまり独自の仮想メモリ空​​間への分割され保護されたアクセスを持つプロセスは、通常Danny物理アドレスを見ることはできません。実際、これは私が聞いたすべてのオペレーティングシステムドライバフレームワークについてかなり決められたルールです。仮想メモリ空​​間内のプロセスに物理メモリアドレスが公開されると、そのエントリは破損しているため、回復する必要があります。悪いルールではありません。ユーザー空間が操作された物理アドレスをカーネルに返すことを許可し、プロセスがアクセスしないメモリにアクセスする危険なミスを防ぎます。

ページテーブルを展開するときは、印刷以外の操作を実行することをお勧めします。これは悪い考えです。なぜなら、それが意味するものが何であれ、バッファが大きくなり、より多くのメモリを割り当てることで潜在的に無限ループが発生する可能性があるからです。さまざまなBSDカーネルとLinuxでプローブを使用してこれらの場所に接続できます。


要約すると、クラシック32ビットx86から​​リング0にあるとき、レジスタはcr3ページテーブルのアドレスを保持する現在のアクティブページディレクトリのアドレスを保持します。これらのページテーブルにバインドされたプロセスは、このレジスタにアクセスできないはずです。

メモリに実際に適用されるビューは、cr4、つまりプロセスコンテキスト識別子が設定されているかどうかによって異なります。

したがって、ページテーブルアドレスにアクセスするには、「カーネルモード」(必要に応じて)で実行する必要がありますが、関心のあるプロセスのページディレクトリベースアドレスをCR3にロードする必要があります。デバッガを介してカーネルメモリから直接データをインポートすることもできます。最後に、別のジョブに切り替えるには、現在のジョブに必要なときに使用できるように、一部の(OS固有の)構造にベースアドレスを保存する必要があります。


仮想化を使用すると、「物理アドレス」は実際にネストされたページテーブル構造の1レベル以上になる可能性があります。半仮想化されたオペレーティングシステムのカーネルは「実際の」物理アドレスを決して見ることができませんが、iommu / smmuの概念を考えると、ここで「実際の」という言葉がどれほど意味があるかさえわかりません。

関連情報