埋め込まれたLinuxユーザースペースとカーネルスペース、プロセスコンテキストと割り込みコンテキスト

序文

  • 以前、組み込みLinuxシステムを学んでいた頃は割り込みコンテキストやプロセスコンテキストに魅了されていて、なじみがありましたが、無理に説明するのは難しいので、思いついたのです。このコンセプトの目的のために、私はインターネット上の多くの情報を読みました。これらの概念の学習は累積的なプロセスです。

ユーザースペースとカーネルスペース

  • 現在のオペレーティングシステムは仮想メモリを使用していることがわかっているため、32ビットオペレーティングシステムの場合、そのアドレス指定スペース(仮想ストレージスペース)は4G(2の32乗)です。心配システムの中核はカーネルです。カーネルは通常のアプリケーションから独立しており、保護されたメモリスペースと、基盤となるハードウェアデバイスにアクセスするためのすべてのアクセス許可にアクセスできます。ユーザープロセスがカーネルを直接操作できないようにし、カーネルのセキュリティを確保するために、心配システムは仮想空間を2つの部分に分割します。1つはカーネル空間で、もう1つはユーザー空間です。Linuxオペレーティングシステムの場合、上位1Gバイト(仮想アドレス0xC0000000から0xFFFFFFFFまで)がカーネルによって使用されます。これはカーネルスペースと呼ばれ、下位3Gバイト(仮想アドレス0x00000000から0xBFFFFFFFまで)は使用するプロセスごとに、ユーザースペースと呼ばれます。**各プロセスはシステム呼び出しを介してカーネルに入ることができます。したがって、Linuxカーネルはシステム内のすべてのプロセスで共有されます。したがって、特定のプロセスの観点から、各プロセスは4Gバイトの仮想空間を持つことができますスペースの割り当てを次の図に示します。
    ここに写真の説明を挿入

  • ユーザースペースとカーネルスペースを使用すると、Linuxの内部構造全体を、下から上に、ハードウェア->カーネルスペース->ユーザースペースの3つの部分分割できます以下に示すように:
    ここに写真の説明を挿入

  • 以下の点に注意してください。
    (1)カーネルコードとデータはカーネルスペースに格納され、ユーザープログラムのコードとデータはプロセスのユーザースペースに格納されます。カーネルスペースであろうとユーザースペースであろうと、それらはすべて仮想スペースにあります。
    (2)Linuxは、2つのレベルの保護メカニズムを使用しますレベル0はカーネル用で、レベル3はユーザープログラム用です。

カーネルモードとユーザーモード

(1)タスク(プロセス)がシステム呼び出しを実行し、カーネルコードで実行される場合、プロセスはカーネル実行状態(カーネル状態)にあると言われますプロセッサは、最高の特権レベル(レベル0)のカーネルコードで実行されています。プロセスがカーネルモードの場合、実行されるカーネルコードは、現在のプロセスのカーネルスタックを使用します。各プロセスには独自のカーネルスタックがあります。

(2)プロセスがユーザー自身のコードを実行しているとき、それはユーザー実行状態(ユーザー状態)にあると言われますこの時点で、プロセッサは最低の特権レベル(レベル3)のユーザーコードで実行されています。ユーザープログラムが実行されていて、割り込みプログラムによって突然中断された場合、ユーザープログラムは、プロセスのカーネル状態にあると象徴的に参照することもできます。割り込みハンドラは現在のプロセスのカーネルスタックを使用するためです。

プロセスコンテキストと割り込みコンテキスト

環境

  • コンテキストは英語のコンテキストから翻訳さます環境を指しますプロセスに関連して、それはプロセスが実行されるときの環境です。具体的には、すべてのレジスタ変数、プロセスによって開かれたファイル、メモリ情報などを含むさまざまな変数とデータです

原子

  • アトム(アトム)とは、もともと「さらに分割できない最小の粒子」を意味し、アトム操作とは「中断できない操作または一連の操作」を意味します。

そして、なぜそのようなコンテキストの概念があるのですか?

  • カーネルスペースとユーザースペースは、最新のオペレーティングシステムの2つの動作モードです。カーネルモジュールはカーネルスペース実行され、ユーザーモードアプリケーションはユーザースペースで実行されますそれらは異なるレベルを表し、システムリソースへの異なるアクセス権を持っています。カーネルモジュールは最高レベル(カーネルモード)で実行され、このレベルでのすべての操作はシステムによって信頼され、アプリケーションは下位レベル(ユーザーモード)で実行されますこのレベルでは、プロセッサがハードウェアへの直接アクセスとメモリへの不正アクセスを制御します。カーネルモードとユーザーモードには、独自のメモリマッピング、つまり独自のアドレススペースがあります。

  • プロセッサは常に次のいずれかの状態にあります。
    (1)カーネルモード、プロセスコンテキスト実行中、カーネルはカーネルスペースで実行中のプロセスを表します。カーネルモード、割り込みコンテキストで実行中、カーネルはカーネルスペースで実行中のハードウェアを表します。
    (2)ユーザーモード、ユーザースペースで実行

  • システムの2つの異なる動作状態には、コンテキストの概念があります。ユーザースペース内のアプリケーションが、物理デバイスの操作やデバイスのアドレスのユーザースペースへのマッピングなど、システムサービスを要求する場合は、システム呼び出しを介して実装する必要がありますシステム呼び出しは、オペレーティングシステムによってユーザースペースに提供されるインターフェイス機能です)。

  • システム呼び出しを通じて、ユーザースペースアプリケーションプログラムはカーネルスペースに入り、カーネルはプロセスに代わってカーネルスペースで実行されます。これには、コンテキストの切り替えが含まれます。ユーザースペースとカーネルスペースには、異なるアドレスマッピング、一般レジスタセットまたは特殊レジスタセットがあります。 、およびユーザースペースプロセスは多くの変数とパラメーターをカーネルに渡す必要があります。また、カーネルはユーザープロセスのレジスターや変数などを保存して、システム呼び出しの終了後にユーザースペースに戻って実行を続行できるようにする必要があります。

プロセスコンテキスト

いわゆるプロセスコンテキストとは、CPUのすべてのレジスタの値、プロセスの状態、およびプロセスの実行時のスタック上のコンテンツを指します。カーネルが別のプロセスに切り替える必要がある場合、現在のプロセスのすべての状態を保存する必要があります。現在のプロセスのプロセスコンテキストを保存して、プロセスが再度実行されたときに、切り替え時の状態を復元して実行を続行できるようにします。

  • プロセスのコンテキストは、ユーザーレベルのコンテキスト、レジスタコンテキスト、およびシステムレベルのコンテキストの3つの部分に分けることができます
    ユーザーコンテキスト:テキスト、データ、ユーザースタック、共有メモリ領域;
    レジスタコンテキスト:一般レジスタ、プログラムレジスタ(IP)、プロセッサステータスレジスタ(EFLAGS)、スタックポインタ(ESP);
    システムレベルコンテキスト:プロセス制御ブロックtask_struct、メモリ管理情報(mm_struct、vm_area_struct、pgd、pte)、カーネルスタック。
    プロセススケジューリングが発生すると、プロセス切り替えはコンテキストスイッチ(コンテキストスイッチ)になります。
  • オペレーティングシステムは、新しくスケジュールされたプロセスを実行する前に、上記のすべての情報を切り替える必要があります。システム呼び出しはモードスイッチ(モードスイッチ)です。モード切り替えの主なタスクはプロセスレジスタのコンテキストを切り替えることであるため、プロセス切り替えと比較して、モード切り替えははるかに簡単で時間を節約できます。
  • プロセスコンテキストは、主に例外ハンドラーとカーネルスレッドです。カーネルがプロセスコンテキストに入る理由は、プロセス自体の一部の作業をカーネルで実行する必要があるためです。たとえば、システム呼び出しは現在のプロセスを処理しますが、例外は通常、処理プロセスによって引き起こされたエラー状態です。したがって、プロセスのコンテキストで現在を参照することは理にかなっています。

割り込みコンテキスト

  • ハードウェアはトリガー信号を介して割り込み信号をCPUに送信し、カーネルに割り込みハンドラーを呼び出してカーネルスペースに入ります。このプロセス中に、一部のハードウェア変数とパラメーターもカーネルに渡され、カーネルはこれらのパラメーターを介して割り込み処理を実行します。
    したがって、「中断コンテキスト」は、ハードウェアおよびカーネルが保存する必要のあるいくつかの環境、主に中断されたプロセスの環境によって渡されるパラメーターとして理解できます。
    カーネルは、割り込み処理または割り込み信号によって引き起こされたソフト割り込みのために、割り込みコンテキストに入ります。割り込み信号の発生はランダムです。割り込みハンドラーとソフト割り込みは、割り込みが発生したときに現在実行中のプロセスを事前に予測できないため、割り込みコンテキストで現在を参照することはできますが、意味がありません。
    実際、Aプロセスが待機したい割り込み信号は、Bプロセスの実行中に発生する可能性があります。たとえば、プロセスAはディスク書き込み操作を開始し、プロセスBはプロセスAがスリープした後に実行され、プロセスBはディスクが書き込まれた後にディスク割り込み信号によって中断され、プロセスAは割り込み処理中にウェイクアップされます。

プロセスコンテキストと割り込みコンテキスト

  • カーネルは、プロセスコンテキストと割り込みコンテキストの2つのコンテキストに存在できます
    システム呼び出しの後、ユーザーアプリケーションはカーネルスペースに入り、カーネルスペースは、ユーザースペース内の対応するプロセスを表すプロセスコンテキストで実行されます
  • 非同期割り込みにより、割り込みハンドラーが呼び出され、割り込みハンドラーが割り込みコンテキストで実行されます
    割り込みコンテキストとプロセスコンテキストを同時に発生させることはできません。プロセスコンテキストで
    実行されているカーネルコードはプリエンプト可能ですが、割り込みコンテキストは最後まで実行され、プリエンプトされません。したがって、カーネルは割り込みコンテキストの作業を制限し、次の操作を実行することを許可しません
  1. スリープ状態に入るか、CPUをアクティブに放棄します。
    割り込みコンテキストはどのプロセスにも属していないため、現在とは関係ありません(ただし、現在は中断されたプロセスを指します)。したがって、割り込みコンテキストがスリープまたはCPUを放棄すると、起動することはできません。したがって、アトミックコンテキストとも呼ばれます。
  2. ミューテックス
    占有する割り込みハンドラーの重要なセクションのリソースを保護するために、ミューテックスは使用できません。セマフォが取得されない場合、コードはスリープ状態になり、上記と同じ状況が発生します。ロックを使用する必要がある場合は、スピンロックが使用されます。
  3. 時間のかかるタスクの実行
    カーネルは多数のサービスと要求に応答する必要があり、割り込みコンテキストはCPU時間を占有するのに時間がかかりすぎ、システム機能に深刻な影響を与えるため、割り込み処理はできるだけ高速にする必要があります。割り込み処理ルーチンで時間のかかるタスクを実行する場合は、割り込み処理ルーチンの下半分で処理する必要があります。
  4. ユーザースペース仮想メモリへのアクセス
    割り込みコンテキストは特定のプロセスに関連していないため、ハードウェアに代わってカーネルスペースで実行されているカーネルであるため、割り込みコンテキストでユーザースペース仮想アドレスにアクセスすることはできません。
  5. 割り込み処理ルーチンは、リエントリー(並列または再帰的に呼び出すことができるルーチン)に設定しないでください。
    割り込みが発生すると、割り込みが戻るまでプリエンプトとirqの両方が無効になるためです。したがって、割り込みコンテキストはプロセスコンテキストと同じではなく、割り込み処理ルーチンの異なるインスタンスをSMPで同時に実行することはできません。
  6. 割り込み処理ルーチンは、より高いレベルのIRQによって中断することができ
    ますが、この割り込みを無効にしたい場合は、割り込みハンドラは、迅速な処理ルーチンとして定義することができ、CPUを伝えるの同等は、ルーチンの実行は、ローカルCPU上のすべての割り込みを無効にしますリクエスト。これの直接的な結果は、他の割り込みが応答で遅延するため、システムパフォーマンスが低下することです。

アトミックコンテキスト

カーネルの基本原則は次のとおりです。割り込みまたはアトミックコンテキストでは、カーネルはユーザースペースにアクセスできず、カーネルはスリープできませんつまり、この場合、カーネルはスリープを引き起こす可能性のある関数を呼び出すことができません。一般的に言えば、アトミックコンテキストは、スピンロックを保持している間、割り込みまたはソフト割り込みを指しますカーネルは、次の状況にあるかどうかを判断するために4つのマクロ提供します

  • これらの4つのマクロによってアクセスされるカウントは、thread_info-> preempt_countです。この変数は実際にはビットマスクです。下位8ビットはプリエンプションカウントを表します。これは通常、spin_lock / spin_unlockによって変更されるか、プログラマーによって強制的に変更され、カーネルで許可される最大プリエンプション深度が256であることを示します。
  • ビット8〜15はソフト割り込みカウントであり、通常はlocal_bh_disable / local_bh_enableによって変更され、カーネルで許可される最大ソフト割り込み深度が256であることを示します。
  • ビット16〜27はハード割り込みカウントであり、通常はenter_irq / exit_irqによって変更され、カーネルで許可される最大ハード割り込み深度が4096であることを示します。
  • 28番目のビットはPREEMPT_ACTIVEフラグです。コードの意味:
    PREEMPT_MASK: 0x000000ff
    SOFTIRQ_MASK: 0x0000ff00
    HARDIRQ_MASK: 0x0fff0000

上記の4つのマクロが1を返す場所はすべて、アトミックコンテキストです。これらは、**カーネルがユーザースペースにアクセスすることを許可しない、カーネルがスリープすることを許可しない、またはスリープを引き起こす可能性のある関数を呼び出すことを許可しません。**これは、thread_info-> preempt_countが0でないことを意味し、プリエンプションが無効になっていることをカーネルに通知します。
ただし、in_atomic()の場合、プリエンプションが有効になっていると非常にうまく機能し、カーネルが現在スピンロックを保持しているかどうか、プリエンプションを無効にするかどうかなどを知ることができます。ただし、プリエンプションが有効になっていない場合、spin_lockはpreempt_countをまったく変更しないため、カーネルがspin_lockを呼び出してスピンロックを保持している場合でも、in_atomic()は0を返します。これは、現在非アトミックコンテキストにあることをカーネルに誤って通知します。したがって、プリエンプションが禁止されている場合、in_atomic()に依存してアトミックコンテキストにあるかどうかを判断するコードは問題があります。

ブログコンテンツリファレンス:https//mp.weixin.qq.com/s?src = 11&timestamp = 1567310917&ver = 1742&signature = QR4lcgtbcKzOvDFLwoqFNplQTjSK7GewpVDBCvNpaXRozYEwcUOrFTqWKf5XsDAp00ySWlARSnQs

おすすめ

転載: blog.csdn.net/qq_41782149/article/details/96754633