127

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

4

3 に答える 3

214
  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()、... - しかし、これは元の質問から少し逸脱しています。

于 2012-10-16T10:23:27.787 に答える
20

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

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

カーネルプログラマーとして、あなたはカーネルが誤ったユーザープログラムから制限されるべきであることを知っています。カーネルとユーザースペースの両方で同じスタックを維持しているとすると、ユーザーアプリケーションの単純なセグメンテーションフォールトによってカーネルがクラッシュし、再起動が必要になります。

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の答えは私には素晴らしく見えます。

于 2012-10-16T10:27:25.630 に答える
5
  1. カーネルスタックとユーザースタックの違いは何ですか

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

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

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

于 2018-08-06T06:50:25.340 に答える