メモリマップとMMU

実は某所でLinuxのメモリ管理についてのレポートを書いているのですが、メモリ管理(特にページング)の理解を難しくしているものがなんなのか、少し考えてみました。

ページング機能自体は基本はとっても簡単です。C言語でのメタファで言ってしまえばポインタのポインタ(のポインタ…)です。アドレスを分割して複数のインデックスに分割して、それぞれを異なるテーブルに順に適用していくだけです。

わたしの思うメモリ管理(ページング)の理解の難しさと、そこから起因するブートプロセスの難しさ(の一部)はPC/ATアーキテクチャのメモリマップと、MMU(メモリ管理ユニット)のブラックボックス化だと思います。

x86のCPUはI/O空間とメモリ空間が分離したアーキテクチャです。ARMやMIPSといったRISCではI/O(周辺機器とのインタフェース)はメモリ空間と一体化していて、特定のアドレスへの書き込みがI/Oへの操作/入力になります。このI/Oに対応したメモリアドレスや、RAMに対応しているアドレスなどの取り決めがメモリマップです。

こう聴くと、じゃあx86PC/ATではアドレス空間は全部メモリなんだなぁ、と思ってしまいますよね。でも実はPC/ATでもメモリマップはあります。BIOSのROM、VGAのメモリやレジスタ、ISAの設定用の空間など、結局いろいろな周辺機器用に(BIOSは周辺機器とは言わないかもしれませんが)メモリ空間の一部がマップされています。

しかしこのメモリマップ、今見るとかなり不自然なものです。昔メモリがとても高価でCPUも貧弱だった頃のメモリ空間向けに決めたメモリマップが互換性のためにずるずると残っているという感じです。このためこれらのアドレスを避けながらRAM部分のみ管理するわけです。これを念頭に置かないと特に 0xC0000000移行のカーネル空間の一様マップの部分の見通しが悪くなります。

またメモリ管理を行っているMMU(Memory Management Unit)というハードウェアユニット(といっても最近のCPUでは内部に組み込まれていますが)のこの散文的な名称と、その内容が今ひとつ実感しにくい事も良くないと思います。わたし自身が最初にLinuxのメモリ管理について書籍を読んだときにはMMUという名称が出てきたところでに挫折しました。そりゃあメモリ管理するためのものだからMMUっていうのは分かるんですけどね、あたりまえすぎて名称が何も伝えてくれないですよね。今でこそ何をやっているのか大体分かりますが、もっとMMUの動作を具体的に記述してくれていればすぐに理解できていたのに、という思いがあります。

というわけでメモリマップとMMUの動作について某所で書こう、と思っているのですがまだ本筋も書き終えてないので今週末に頑張って見るつもりです。