d.sunnyone.org
sunnyone.org

ページ

2011-11-30

Solaris/x86のスタック領域がなぜ低位に確保されるのか?

藤原さんの「理解した気分になる Solaris Internals "Chapter 9: Virtual Memory" 総ざらえ」の疑問
x86 のスタック領域がアドレス低位に確保されるのは、 Solaris 固有の話?それとも他の OS でも共通の、CPU 固有の話?
の答え、ちょっと調べた感じだと、どうも歴史的なもののようです。
(質問の回答としては、Solaris固有ではないが、CPU固有といえば固有、他のOSでも共通かどうかは不明というところでしょうか。)

まず話を聞いていない人向けに書くと、Solaris/SPARC(32bit,64bit)やSolaris/x64はそんなことないのに、
Solaris/x86だけ、スタックが妙に低いアドレス(0x8048000)から伸びているけどなんぞ、というお話です。
cf. Solaris Internalsの図

このアドレスがキーなのかと思って検索してみたらどうもそうのようで、このアドレスは
ELFのエントリポイントの模様。

リンカとかローダの話ですかと思って手元の「Linkers & Loaders」を調べてみたら、まさにそれっぽい記述を見つけました。
ELFがa.outと異なるのは、オブジェクトを0番地付近ではなくアドレス空間の中程にロードして、スタックがテキストセグメントの下位から成長し、ヒープがデータセグメントの終端から成長するようにすることによって、全体として利用するアドレス空間が比較的小さく済むようにしている点である。386システムでは、テキストのベースアドレスは0x08048000で、テキストの前の0x08000000以降の部分に十分に大きなスタックを確保できると同時に、ほとんどのプログラムでは第2レベルのページテーブルは1つだけで済む(386においては、1つの第2レベルテーブルで0x00400000のアドレスをマップできる)。
決めた時代的には、ここに置くとアドレスがいい感じだったということのようですね。

なおこれを決めたのは「Re: is not 0x8048000 too wasteful?--about virtual address layout」によると、
There is folklore that 0x08048000 once was STACK_TOP (that is, the stack
grew downwards from near 0x08048000 towards 0) on a port of *NIX to i386
that was promulgated by a group from Santa Cruz, California. This was
when 128MB of RAM was expensive, and 4GB of RAM was unthinkable.
ということで、1983年のSCOでしょうか。

ちなみに、Linux/x86 (2.6)は上記場所にスタックはできないようです。


なお、もっと詳しい方がいればブログなりでフォローいただければ修正します :)

ちなみにこの「Linkers & Loaders」、ひさびさに読み始めてたのですが、本を見ると2001年初版。出た当初に買ったはず(だいぶ色あせてる)なので、10年後にまた読むとは。前知識なしで読むと全然わからない(10年前がそうだった)ですが、最近のx86やらOSやらの勉強でようやくわかるようになってきました。
Amazonの評価はよくないですが、これだけ一通り書いてあってもし読みやすい本があれば是非知りたい感じです。

0 件のコメント:

コメントを投稿