カーネルスタックとユーザー空間スタック


110

カーネルスタックとユーザースタックの違いは何ですか?カーネルスタックを使用する理由 ローカル変数がISRで宣言されている場合、それはどこに格納されますか?各プロセスには独自のカーネルスタックがありますか?次に、プロセスはこれらの両方のスタック間でどのように調整しますか?

回答:


187
  1. カーネルスタックとユーザースタックの違いは何ですか?

要するに、何もない-メモリ内の別の場所(したがって、スタックポインタレジスタの別の値)を使用することを除いて、通常は別のメモリアクセス保護。つまり、ユーザーモードで実行する場合、カーネルメモリ(その一部はカーネルスタックです)は、マップされていてもアクセスできません。逆に、カーネルコードから明示的に要求されない限り(Linuxでは、などの関数を介してcopy_from_user())、ユーザーメモリ(ユーザースタックを含む)には通常、直接アクセスできません。

  1. [別の]カーネルスタックが使用されるのはなぜですか?

特権とセキュリティの分離。1つは、ユーザー空間プログラムはスタック(ポインタ)を好きなように作成できることであり、通常、有効なものを用意するだけのアーキテクチャ要件はありません。したがって、カーネルは、ユーザースペースのスタックポインタが有効でも使用可能でも信頼できないため、独自の制御下で1つのセットを必要とします。異なるCPUアーキテクチャは、これを異なる方法で実装します。x86 CPUは、特権モードの切り替えが発生すると自動的にスタックポインターを切り替え、さまざまな特権レベルに使用される値は、特権コード(つまり、カーネルのみ)によって構成可能です。

  1. ISRでローカル変数が宣言されている場合、それはどこに格納されますか?

カーネルスタック上。カーネル(Linuxカーネル)は ISRを直接x86アーキテクチャの割り込みゲートにフックしませが、代わりに、割り込みディスパッチを、登録済みハンドラーを呼び出す前に割り込み前のレジスタ状態を保存する共通のカーネル割り込みエントリ/出口メカニズムに委任します。 。割り込みをディスパッチするときのCPU自体が特権やスタックスイッチを実行する可能性があり、これはカーネルによって使用/設定されるため、共通の割り込みエントリコードはすでに存在するカーネルスタックに依存できます。
つまり、カーネルコードの実行中に発生する割り込みは、その時点でカーネルスタックをそのまま(引き続き)使用します。これは、割り込みハンドラーが深くネストされた呼び出しパスを持っている場合、スタックオーバーフローを引き起こす可能性があります(深いカーネル呼び出しパスが中断され、ハンドラーが別の深いパスを引き起こす場合.Linuxでは、iptablesがアクティブなネットワークコードによってファイルシステム/ソフトウェアRAIDコードが中断されますチューニングされていない古いカーネルでそのようなトリガーとなることが知られています...ソリューションは、そのようなワークロードのカーネルスタックサイズを増やすことです)。

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

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

  1. プロセスはこれらの両方のスタック間でどのように調整しますか?

いいえ、必要ありません。スケジューリング(どのように/異なるスレッドが実行されているか、その状態がどのように保存および復元されるか)は、オペレーティングシステムのタスクであり、プロセスはこれに関与する必要はありません。スレッドが作成されると(各プロセスには少なくとも1つのスレッドが必要です)、カーネルはそれらのカーネルスタックを作成しますが、ユーザー空間スタックは、スレッドの作成に使用されるメカニズム(呼び出し元のような関数makecontext()またはpthread_create()呼び出しを許可する関数)によって明示的に作成または提供されます。「子」スレッドのスタックに使用するメモリ領域を指定する)または(新しいプロセスを作成するときに、通常「コピーオンライト」/ COWと呼ばれるオンアクセスメモリクローンによって)継承されます。
それは言った、(状態、その中のスレッドのスタックポインタ)。UNIX信号は、:あり、このために複数の方法がありますがsetcontext()pthread_yield()/ pthread_cancel()、... -これは元の質問から少しdisgressingています。


すばらしい答えFrankH。ありがとう。
kumar 2013

1
@FrankHすばらしい答えですが、これに関連する小さな質問がありますが、ARMアーキテクチャでは..このカーネルスタックは、さまざまなプロセッサモードにどのように関連していますか?
Rahul

2
@Rahul:「SOコメントのマージンが小さすぎて、そのような回答を含めることができません」。スタック/スタックポインターレジスタがさまざまなARM CPUモード(バンクされたSPを実装するモード)でどのように機能するかは良い質問ですが、コメントよりも多くのスペースが必要です。同じことがx86タスクゲートやISTなどにも当てはまります。「単一」のカーネルスタックポインター(「単一」のユーザースタックポインターが存在しないのと同じように)のようなものはありません。異なる動作モードでの個別のスタックポインタは、非常にハードウェアに依存します。
FrankH。

@FrankH。私は同じ...のために新しい質問を作成しstackoverflow.com/q/22601165/769260私はあなたが:)スペースを気にすることなく私を助けることができる今を願って
ラーフル

1
@FrankH。プロセスのメモリレイアウトでカーネルスタックが属する場所を示す図を提供できますか?
Jithin Pavithran

19

私の答えは、他のSOの質問から収集したものです。

What's the difference between kernel stack and user stack?

カーネルプログラマーは、カーネルを誤ったユーザープログラムから制限する必要があることを知っています。カーネルとユーザー空間の両方で同じスタックを保持するとします。その後、ユーザーアプリケーションの単純なsegfaultがカーネルをクラッシュさせ、再起動が必要になるとします。

ISRスタックのようにCPUごとに1つの「カーネルスタック」と、プロセスごとに1つの「カーネルスタック」があります。各スレッドには、ユーザースレッドとカーネルスレッドの両方を含む独自のスタックがありますが、プロセスごとに1つの「ユーザースタック」があります。

http://linux.derkeiler.com/Mailing-Lists/Kernel/2004-10/3194.html

Why kernel stack is used?

したがって、カーネルモードでは、関数呼び出し、ユーザー空間と同様のローカル変数を処理するために、スタックのようなメカニズムが必要です。

http://www.kernel.org/doc/Documentation/x86/kernel-stacks

If a local variable is declared in an ISR, where it will be stored?

ISRスタック(IRQSTACKSIZE)に格納されます。ISRは、ハードウェアがサポートしている場合にのみ、別の割り込みスタックで実行されます。それ以外の場合、ISRスタックフレームは、中断されたスレッドのスタックにプッシュされます。

ユーザー空間は、割り込みが現在のプロセスのカーネルスタックで処理されるのか、別のISRスタックで処理されるのかを知りませんし、率直に言っても気にしません。割り込みはCPUごとに発生するため、ISRスタックはCPUごとでなければなりません。

 Does each process has its own kernel stack ?

はい。各プロセスには、独自のカーネルスタックがあります。

 Then how the process coordinates between both these stacks?

@FrankHの答えは私には素晴らしく見えます。


4
  1. カーネルスタックとユーザースタックの違いは何ですか

Robert LoveのLinux Kernel Developmentを参考にすると、主な違いはサイズです。

ユーザー空間は、巨大な構造や1000要素の配列など、スタック上の多くの変数を静的に割り当てることで回避できます。
ユーザー空間には動的に拡大できる大きなスタックがあるため、この動作は合法です。
カーネルスタックは大きくも動的でもありません。それは小さく、サイズは固定されています。
カーネルのスタックの正確なサイズは、アーキテクチャによって異なります。
x86では、スタックサイズはコンパイル時に構成可能で、4KBまたは8KBのいずれかです。
歴史的に、カーネルスタックは2ページです。つまり、32ビットアーキテクチャでは8KB、64ビットアーキテクチャでは16KBです。このサイズは固定で絶対です。
各プロセスは独自のスタックを受け取ります。

また、カーネルスタックには、スレッドに関する情報を保持するthread_info構造体へのポインターが含まれています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.