64 ビット ボックスの Linux 2.6.32 でのプロセス実行について調べています。の出力を調べているときに/proc/$PID/maps
、1 つのことを観察しました。
$ cat /proc/2203/maps | head -1
00400000-004d9000 r-xp 00000000 08:02 1050631 /bin/bash
$ cat /proc/27032/maps | head -1
00400000-00404000 r-xp 00000000 08:02 771580 /sbin/getty
すべてのプログラムのmaps
ファイルは、各プログラムの実行可能コードが から始まるメモリ ブロックにロードされていることを示しているようです0x00400000
。
これらが仮想アドレスであることは理解しています。ただし、これらのアドレスが複数の同時実行プロセスでどのように同じになるかはわかりません。すべてのプロセスをロードするために共通の開始アドレスを使用する理由は何ですか? また、OS はプロセス間の仮想ロード ポイントをどのように区別しますか?
編集:
ページングを使用したアドレス空間の仮想化に関する私の理解から、仮想アドレスの一部は、メモリ ブロック (フレーム) の物理アドレスを検索するために使用され、それを使用して 1 つ以上のページ テーブルにインデックスを付けることができると考えました。この場合を考えてみましょう。アドレスは 32 ビットに見えます (これは私を困惑させるもう 1 つのことです。プログラムのアドレスは 32 ビットなのに、ロードされたライブラリのアドレスは 64 ビットなのはなぜですか?)。ページ ディレクトリ エントリ、ページ テーブル エントリ、およびページ オフセットにそれぞれ対応する 10、10、および 12 ビットにアドレスを分割することは、0x00400000
常に「ページ ディレクトリ エントリ 1、ページ テーブル エントリ 0、オフセット 0」を意味するわけではありません。アドレス変換を実行するプログラムは何ですか?
これがどのように行われるかを確認する方法の 1 つは、OS がページ ディレクトリ エントリ #1 を変更して、タスク スイッチが実行されるたびにプログラムに対応するページ テーブルを指すようにすることです。その場合、複雑さが増しているように思えます。プログラム コードが位置に依存しないことを考えると、プログラムを任意の仮想アドレスにロードしてそこから移動する方が簡単ではないでしょうか?