4

Linux の深い働きについて質問がありました。

CPUでマルチスレッドプロセスが実行されているとしましょう。このような場合、CPU 上で実行されているスレッドがあります。より広い視野で、実行のためにRAMにロードされているプロセスに属する対応するページがあります。

スレッドがシステムコールを行うとしましょう。この後の仕組みはちょっとわかりません。割り込みは呼び出しを生成します。私の質問の 1 つは、誰がこの電話に応答するかということです。

システムに m:n ユーザー レベル スレッドからカーネル レベル スレッドへのマッピングがあるとします。対応するカーネル レベル スレッドがこの呼び出しに応答すると想定しています。

そのため、カーネルは割り込みベクター テーブルを検索し、実行する必要があるルーチンを取得します。次の質問は、割り込みの実行にどのスタックが使用されるかということです。カーネル スレッドのスタックですか、それともユーザー レベルのスレッドのスタックですか? (カーネルスレッドのスタックになると思います。)

プログラムの流れに戻って、操作が を使用してファイルを開くとしましょうfopen。次の質問は、ISR からシステム コールへのジャンプがどのように行われるかということです。それとも、ISR はシステム コールにマップされていますか?

また、カーネルスレッドが実行されているときのより広い図では、システムコールを実行しているページを格納するために RAM 上の「OS 領域」が使用されると想定しています。

もう一度別の角度から見てください (あなたがまだ私と一緒にいることを願っています) 最後に、対応するカーネル スレッドが CPU スケジューラによって処理されていると想定しています。コンテキスト スイッチでは、ユーザー レベル スレッドから対応するカーネル レベル スレッドへの切り替えが発生します。fopenシステムコールが応答されたとき。

私は多くの仮定を立てましたが、誰かが疑問を解消するか、少なくとも私を正しい方向に導くことができれば、それは絶対に素晴らしいことです.

4

1 に答える 1

9

注: 私は主に ARM マシンを使用しているため、これらのいくつかは ARM 固有のものである可能性があります。また、できるだけシンプルにしようと思います。間違っている、または単純化しすぎている可能性があるものは、自由に修正してください。

スレッドがシステムコールを行うとしましょう。この後の仕組みはちょっとわかりません。割り込みは呼び出しを生成します。私の質問の 1 つは、誰がこの電話に応答するかということです。

通常、プロセッサは、カーネル モードで所定の場所で実行を開始します。カーネルは現在のプロセス状態を保存し、ユーザー空間レジスタを調べて、要求されたシステム コールを特定し、それを正しいシステム コール ハンドラにディスパッチします。

そのため、カーネルは割り込みベクター テーブルを検索し、実行する必要があるルーチンを取得します。次の質問は、割り込みの実行にどのスタックが使用されるかということです。カーネル スレッドのスタックですか、それともユーザー レベルのスレッドのスタックですか? (カーネルスレッドのスタックになると思います。)

カーネルスタックに切り替わると確信しています。ユーザー空間スタックを使用した場合、情報漏えいに関するかなり深刻なセキュリティ上の問題が発生します。

プログラムの流れに戻って、操作が fopen を使用してファイルを開くとしましょう。次の質問は、ISR からシステム コールへのジャンプがどのように行われるかということです。それとも、ISR はシステム コールにマップされていますか?

fopen()実際にはlibc関数であり、システムコール自体ではありません. open()ただし、実装でsyscallを呼び出す場合があります(ほとんどの場合は呼び出します) 。

したがって、プロセスは(大まかに)次のとおりです。

  1. ユーザー空間呼び出しfopen()
  2. fopenへのシステムコールを実行しますopen()
  3. これにより、ある種の例外または割り込みがトリガーされます。それに応じて、プロセッサはより特権的なモードに切り替わり、カーネル内の事前設定された場所で実行を開始します。
  4. カーネルは、割り込みと例外の種類を判断し、適切に処理します。私たちの場合、それはシステムコールになります。
  5. カーネルは、ユーザー空間のレジスタを読み取ることで、どのシステム コールが要求されているかを判断し、引数を抽出して適切なハンドラに渡します。
  6. ハンドラが実行されます。
  7. カーネルは、戻りコードをユーザー空間レジスターに入れます。
  8. カーネルは、例外が発生した場所に実行を戻します。

また、カーネルスレッドが実行されているときのより広い図では、システムコールを実行しているページを格納するために RAM 上の「OS 領域」が使用されると想定しています。

ページは何も実行しません:) 通常、Linux では、0xC0000000 より上にマップされたアドレスはカーネルに属します。

もう一度別の角度から見てください (あなたがまだ私と一緒にいることを願っています) 最後に、対応するカーネル スレッドが CPU スケジューラによって処理されていると想定しています。コンテキスト スイッチでは、ユーザー レベル スレッドから対応するカーネル レベル スレッドへの切り替えが発生します。 fopen システム コールが応答されたとき。

プリエンプティブ カーネルを使用すると、スレッドは効果的に差別されません。私の理解では、新しいスレッドはシステム コールを処理する目的で作成されるのではなく、カーネル モードを除いて、システム コールが要求されたのと同じスレッドで実行されるだけです。

つまり、システム コールを処理するカーネル モードのスレッドは、他のスレッドと同じようにスケジュール アウトできます。したがって、これは、カーネル用に開発するときに「ユーザー空間コンテキスト」について耳にする場所です。これは、ユーザーモード スレッドでカーネル モードで実行されていることを意味します。

これを説明するのは少し難しいので、うまくいくことを願っています。

于 2013-04-10T10:09:14.520 に答える