私は、Linuxを実行している最新のx86システムで、IOデバイスが「一般的な」メモリアドレス空間にどのようにマッピングされるかを理解したいと思います。
私が理解したいいくつかの詳細は次のとおりです。
cat /proc/iomem
IOメモリマッピング領域のリストを印刷します(印刷物理住所)が不連続です。これらの領域は、カーネルモジュールによって実行時に動的に要求され、<linux / ioport.h>で定義されているrequest_mem_region関数を介して割り当てることができます。
x86マシンは、
mov
メモリアクセスとIO(メモリにマッピングされている)の両方に使用されます。
カーネルモジュールコードが実行されていると仮定すると、mov [value] [virtual address]
mmio領域を参照できる仮想アドレスやメモリに存在する「正常」データ値などのコマンドに遭遇する可能性があります。 「一般」メモリからmmioトラフィックを分離するプロセスには、2つの主要な手順があります。
- 決めるもしアドレスはmmioです。ページテーブルにはメモリマッピングがあるかどうかを示すフラグがあるため、ページテーブル変換を実行するときにmmuがそれを決定すると仮定します。
- 新しく作成された物理アドレス(ページテーブル変換の出力であるmmu)の「IOアドレス」を決定し、それをIOとインタフェースするすべてのチップ(ノースブリッジ、ルートコンプレックスなど)に渡します。
質問1:上記のステップ1を正しく理解していますか?
質問2:ステップ2はどのように進行しますか? (どういう意味で実在地図はどのように保存されますか? )
確認する必要がある範囲は/proc/iomemにリストされています。ここから取得するデータは次のマップのようです。
map[mmio_address] = io_address_object
このようなことが起こっていることを覚えておいてください以内にmov
CPUの観点から、単一命令のコンテキストを見ると、これらの変換がCPU外部ハードウェア以外の他のものによってどのように発生するかがわかりません。
答え1
ステップ1の理解が正確です。 MMU は、対応する仮想アドレスのページテーブルエントリをチェックして、アドレスが MMIO かどうかを判断します。
ステップ2で、物理アドレスを対応するIOアドレスにマッピングする役割を担うオブジェクトは、マザーボードのチップセットです。チップセットには、通常、CPUのIO要求を処理し、それをシステムに接続されたさまざまなIOデバイスが理解できる信号に変換するMMIO(Memory Mapped IO)コントローラが含まれています。
MMIOコントローラは通常、各MMIOアドレス範囲を各IOデバイスの対応するIOアドレス範囲にマッピングするメモリマップを維持する。このメモリマップは通常、チップセット内のハードウェアレジスタに格納され、システムの初期化中にBIOSによってプログラムされます。
CPUがMMIO操作を実行すると、MMUは仮想アドレスを物理アドレスに変換し、それをMMIOコントローラに送信します。 MMIOコントローラは、メモリマッピングを使用して物理アドレスに対応するIOアドレスを決定し、適切なIO信号を生成してIOデバイスと通信します。
要約すると、MMIOアドレスとIOアドレス間のマッピングはチップセットのMMIOコントローラによって維持され、このマッピングはシステム初期化中にBIOSによってプログラムされます。