プログラムのメモリレイアウトでは、「カーネルスタック」、「Cランタイム起動関数のフレーム」、および「main()のフレーム」はどこにありますか?

プログラムのメモリレイアウトでは、「カーネルスタック」、「Cランタイム起動関数のフレーム」、および「main()のフレーム」はどこにありますか?

Linuxプログラミングインターフェースでは:

ここに画像の説明を入力してください。

  1. 上の図では、カーネルスタック(下記の引用に記載)はどこにありますか?

    上の図の上部「カーネル(プロセス仮想メモリにマップされますがプログラムではアクセスしません)」ですか?

    用語 ユーザースタック ここで説明するスタックをカーネルスタックと区別するために使用されます。カーネルスタックシステムコールの実行中に内部的に呼び出される関数のスタックとして使用されるカーネルメモリに保持されるプロセス固有のメモリ領域。 (カーネルは、ユーザースタックが保護されていないユーザーメモリにあるため、この目的には使用できません。)

  2. 上の図では、「Cランタイム起動機能のフレームワーク」と「main()のフレームワーク」(以下の図に記載)はどこにありますか?

    上の図の「argv、Environ」は、「Cランタイム開始関数のフレームワーク」、「main()のフレームワーク」、またはその両方の一部ですか?

    ここに画像の説明を入力してください。

  3. 0x00000000と0x08048000の間の最も低いセグメントの目的は何ですか?

ありがとうございます。

答え1

  1. そうではありませんカーネルスタック。各スレッドには、プロセスがシステムコールを行うときにスタック空間として使用されるメモリ領域があります。また、割り込みハンドラが使用する CPU ごとに 1 つずつ別々の「割り込みスタック」があります。これらのメモリ領域はカーネルアドレス空間(上の0xc0000000図を参照)にあります。

  2. スタックフレーム(Cランタイムフレーム、メインフレームなど)はスタックの一部です。プロセスパラメータ(argv)と環境は別々の領域であり、スタックの一部ではありません。

  3. 0x0との間の領域0x08048000(約128MB)は、いかなる用途にも使用されません。もともとi386 System V ABIはスタック用にこの領域を予約していましたが、Linuxは動作が異なります。この領域を使用しないことは、RAMを無駄にするのではなく、その領域がマップされないためにアドレス空間を無駄にすることです。この情報は、32ビットx86アーキテクチャでどのように実行されるかを説明しているため、これはほとんど完全に最新の情報ではありません。今日、32ビット専用のx86システムは見つけるのが難しく、ディストリビューションはそれをサポートすることを段階的に停止しています。

答え2

から引用csapp 3位第9章:

ここに画像の説明を入力してください。

カーネル仮想メモリの異なる領域には、プロセスごとに異なるデータが含まれています。例には、ページテーブル、プロセスコンテキストでコードを実行するときにカーネルが使用するスタック、仮想アドレス空間の現在の構成を追跡するさまざまなデータ構造などがあります。

私はすべてのプロセスにカーネルスタックがあると思います。少なくともシステムコールを実行している場合は、データを保存するために管理者権限を必要とするカーネル組み込み機能を呼び出すことができます。カーネル割り込みハンドラでも動作します。

関連回答

  1. 各プロセスには独自のカーネルスタックがありますか?

すべてのプロセスだけでなく、すべてのスレッドには独自のカーネルスタック(実際には独自のユーザースタック)があります。プロセスとスレッド(Linuxの場合)の唯一の違いは、複数のスレッドがアドレス空間を共有できることです(プロセス形成)。

関連情報