仮想アドレスと物理アドレスをマップするアドレス変換は理解したが、実際にどのようにマップされているのかを解説。
ページング
メモリアドレス空間を固定長の領域(ページ)に分け、ページごとにアドレスをマップする方式。
x86-64の64ビットモードではページの大きさは4KiB、2MiB、1GiBから選択できる。
※実際にアドレス変換を行うハードウェアをMMU(memory management unit)と呼ぶ。MMUはCPUに内蔵されており、アドレス変換とメモリ権限のチェックを行う。
重要なのは、仮想アドレスは連続値である必要があるが、物理アドレスはバラバラの位置にあって良い。
※そもそも仮想アドレスを連続的に取るための方式なので当たり前。
仮想アドレスを新規に割り当てる時は、アプリケーションが使用できるメモリ領域にiページ分(2MiB程度)の連続した領域を確保できるかを全探索する。できれば割り当てるし、できないのであればどこかをfree()させる。
階層ページング
仮想アドレス→物理アドレスに変換するためには複数のテーブルを経由する構造。
例
仮想アドレス:oxffff800000003120
↓
実際の値(2進数)
1...1 | 1 0000 0000 | 0 0000 0000 | 0 0000 0011 | 0001 0010 0000 |
ビット数(64ビット)
64~48|47~39|38~30|29~21|20~12|11~0|
↓
- 64~48 は固定(47ビット目と同じ値に設定する)
- 47~39:256
- 38~30:0
- 29~21:0
- 20~12:0
- 11~0:120(オフセット)
CR3→PML4[256]→PDP[0]→PD[0]→PT[0]→+オフセット(120)→ 0x150120
このように仮想アドレスが階層的に物理アドレスに変換される
リニアアドレス
通常はソフトウェアは論理アドレスを指定する。その後セグメンテーションにより論理アドレス→リニアアドレスに変換される。しかし、64ビットモードではセグメンテーションによるアドレス変換は行われないので、論理アドレス=リニアアドレスとなる。
参考文献
- ゼロからのOS自作入門 (http://zero.osdev.jp/)