オペレーティングシステムのユーザーモードとカーネルモードの違いは何ですか?


104

ユーザーモードとカーネルモードの違いは何ですか?なぜ、どのようにしてどちらをアクティブにするのですか?また、それらの使用例は何ですか?



1
@ CiroSantilli709大掴捕六四事件法轮功7年前に尋ねられた質問は、6年前に尋ねられた質問の複製としてクローズすることはできません。それらが実際に重複している場合、クロージャーは他の方法で回避する必要があります。
サルバドールダリ2017年

2
@SalvadorDaliこんにちは、現在のコンセンサスは「品質」で終了することです:meta.stackexchange.com/questions/147643/…「品質」は測定できないので、私は賛成票で投票します。;-)おそらく、どの質問がタイトルの最も新しいGoogleキーワードにヒットしたかによるものです。下に免責事項を追加して回答をコピーし、閉じた場合に備えてこのリンクからリンクすることをお勧めします。
Ciro Santilli郝海东冠状病六四事件法轮功

回答:


143
  1. カーネルモード

    カーネルモードでは、実行中のコードは基盤となるハードウェアに完全かつ無制限にアクセスできます。任意のCPU命令を実行し、任意のメモリアドレスを参照できます。カーネルモードは通常、オペレーティングシステムの最低レベルの最も信頼できる機能のために予約されています。カーネルモードでのクラッシュは壊滅的です。彼らはPC全体を停止させます。

  2. ユーザーモード

    ユーザーモードでは、実行コードはハードウェアまたは参照メモリに直接アクセスすることができません。ユーザーモードで実行されているコードは、システムAPIに委任して、ハードウェアまたはメモリにアクセスする必要があります。この種の分離によって提供される保護のため、ユーザーモードでのクラッシュは常に回復可能です。コンピューターで実行されているコードのほとんどは、ユーザーモードで実行されます。

続きを読む

ユーザーモードとカーネルモードについて


CPUがオペレーティングシステムコードを実行しているとき、プロセッサはどのモードですか?
JackieLam 2013年

2
@JackieLam:カーネルモードである必要があります。
カディナ2014

それ自体、ユーザー空間プロセスを実行するには、カーネル空間にマップする必要がありますか?
roottraveller 2017

@rahul参照メモリがユーザーモードで取得できるか、Javaのような言語で最も単純な操作データが高価なモード変更をもたらすかどうかは疑問です。
maki XIE

48

これらは、コンピュータが動作する2つの異なるモードです。これ以前は、コンピューターが大きな部屋のようだったときに、何かがクラッシュした場合、コンピューター全体が停止しました。したがって、コンピューターアーキテクトはそれを変更することにしました。最近のマイクロプロセッサは、ハードウェアに少なくとも2つの異なる状態を実装しています。

ユーザーモード:

  • すべてのユーザープログラムが実行されるモード。RAMやハードウェアにはアクセスできません。これは、すべてのプログラムがカーネルモードで実行されると、互いのメモリを上書きできるためです。これらの機能のいずれかにアクセスする必要がある場合は、基盤となるAPIを呼び出します。システムプロセスを除く、Windowsによって開始された各プロセスは、ユーザーモードで実行されます。

カーネルモード:

  • すべてのカーネルプログラムが実行されるモード(異なるドライバー)。すべてのリソースと基盤となるハードウェアにアクセスできます。任意のCPU命令を実行でき、すべてのメモリアドレスにアクセスできます。このモードは、最低レベルで動作するドライバー用に予約されています

切り替えの発生方法。

ユーザーモードからカーネルモードへの切り替えは、CPUによって自動的には行われません。CPUは割り込み(タイマー、キーボード、I / O)によって中断されます。割り込みが発生すると、CPUは現在実行中のプログラムの実行を停止し、カーネルモードに切り替えて、割り込みハンドラを実行します。このハンドラーは、CPUの状態を保存し、その操作を実行して、状態を復元し、ユーザーモードに戻ります。

http://en.wikibooks.org/wiki/Windows_Programming/User_Mode_vs_Kernel_Mode

http://tldp.org/HOWTO/KernelAnalysis-HOWTO-3.html

http://en.wikipedia.org/wiki/Direct_memory_access

http://en.wikipedia.org/wiki/Interrupt_request


CPUがオペレーティングシステムコードを実行しているとき、プロセッサはどのモードですか?
JackieLam 2013年

1
@JackieLam:カーネルモード
Apurv Nerlekar

10

Windowsを実行しているコンピューターのプロセッサには、ユーザーモードとカーネルモードの2つの異なるモードがあります。プロセッサは、プロセッサで実行されているコードのタイプに応じて、2つのモードを切り替えます。アプリケーションはユーザーモードで実行され、コアオペレーティングシステムコンポーネントはカーネルモードで実行されます。多くのドライバーはカーネルモードで実行されますが、一部のドライバーはユーザーモードで実行される場合があります。

ユーザーモードアプリケーションを起動すると、Windowsはアプリケーションのプロセスを作成します。このプロセスは、アプリケーションにプライベート仮想アドレススペースとプライベートハンドルテーブルを提供します。アプリケーションの仮想アドレス空間はプライベートであるため、1つのアプリケーションが別のアプリケーションに属するデータを変更することはできません。各アプリケーションは分離して実行され、アプリケーションがクラッシュした場合、クラッシュはその1つのアプリケーションに限定されます。他のアプリケーションとオペレーティングシステムは、クラッシュの影響を受けません。

プライベートであることに加えて、ユーザーモードアプリケーションの仮想アドレス空間は制限されています。ユーザーモードで実行されているプロセッサは、オペレーティングシステム用に予約されている仮想アドレスにアクセスできません。ユーザーモードアプリケーションの仮想アドレススペースを制限することで、アプリケーションが重要なオペレーティングシステムデータを変更したり、損傷したりするのを防ぐことができます。

カーネルモードで実行されるすべてのコードは、単一の仮想アドレス空間を共有します。これは、カーネルモードドライバーが他のドライバーやオペレーティングシステム自体から分離されていないことを意味します。カーネルモードドライバーが誤った仮想アドレスに誤って書き込むと、オペレーティングシステムまたは別のドライバーに属するデータが危険にさらされる可能性があります。カーネルモードドライバーがクラッシュすると、オペレーティングシステム全体がクラッシュします。

あなたがWindowsユーザーであれば、このリンクを一度通過すると、さらに多くを得るでしょう。

ユーザーモードとカーネルモード間の通信


6

CPUリングは最も明確な違いです

x86保護モードでは、CPUは常に4つのリングのいずれかにあります。Linuxカーネルは0と3のみを使用します。

  • カーネルの場合は0
  • ユーザー用3

これは、カーネル対ユーザーランドの最もハードで高速な定義です。

Linuxがリング1および2を使用しない理由:CPU特権リング:リング1および2が使用されないのはなぜですか?

現在のリングはどのように決定されますか?

現在のリングは、次の組み合わせで選択されます。

  • グローバル記述子テーブル:GDTエントリのメモリ内テーブル。各エントリにはPrivl、リングをエンコードするフィールドがあります。

    LGDT命令は、アドレスを現在の記述子テーブルに設定します。

    参照:http : //wiki.osdev.org/Global_Descriptor_Table

  • セグメントは、GDTのエントリのインデックスを指すCS、DSなどを登録します。

    たとえばCS = 0、GDTの最初のエントリが実行中のコードに対して現在アクティブであることを意味します。

各リングは何ができますか?

CPUチップは、次のように物理的に構築されています。

  • リング0は何でもできます

  • ring 3は、いくつかの命令を実行して、いくつかのレジスタに書き込むことができません。

    • 自分のリングを変更することはできません!そうでなければ、それ自体がリング0に設定され、リングは役に立たなくなります。

      つまり、現在のリングを決定する現在のセグメント記述子を変更できません。

    • はページテーブルを変更できません:x86ページングは​​どのように機能しますか?

      つまり、CR3レジスタを変更できず、ページング自体がページテーブルの変更を防ぎます。

      これにより、セキュリティ/プログラミングの容易さのために、1つのプロセスが他のプロセスのメモリを参照できなくなります。

    • 割り込みハンドラを登録できません。それらはメモリ位置への書き込みによって構成されますが、これもページングによって防止されます。

      ハンドラーはリング0で実行され、セキュリティモデルに違反します。

      つまり、LGDTおよびLIDT命令は使用できません。

    • inおよびのようなIO命令を実行できないoutため、任意のハードウェアアクセスが可能です。

      それ以外の場合、たとえば、プログラムがディスクから直接読み取ることができる場合、ファイルのアクセス許可は役に立ちません。

      より正確にはMichael Petchに感謝します。実際には、OSがリング3でIO命令を許可することが可能です。これは、実際にはTask状態セグメントによって制御されます

      リング3がそれを最初から持っていなかった場合、リング3がそれを許可することは不可能です。

      Linuxは常にそれを拒否します。参照:LinuxがTSS経由でハードウェアコンテキストスイッチを使用しないのはなぜですか?

プログラムとオペレーティングシステムはリング間でどのように移行しますか?

  • CPUがオンになると、リング0で初期プログラムの実行を開始します(まあ、それは良い概算です)。この初期プログラムはカーネルであると考えることができます(ただし、通常は、まだリング0にあるカーネルを呼び出すブートローダーです)。

  • ユーザランドのプロセスがカーネルは、ファイルへの書き込みのようにそれのために何かをしたいとき、それはそのような割り込み生成指示使用していますint 0x80syscallカーネルを知らせるために。x86-64 Linux syscall hello worldの例:

    .data
    hello_world:
        .ascii "hello world\n"
        hello_world_len = . - hello_world
    .text
    .global _start
    _start:
        /* write */
        mov $1, %rax
        mov $1, %rdi
        mov $hello_world, %rsi
        mov $hello_world_len, %rdx
        syscall
    
        /* exit */
        mov $60, %rax
        mov $0, %rdi
        syscall
    

    コンパイルして実行:

    as -o hello_world.o hello_world.S
    ld -o hello_world.out hello_world.o
    ./hello_world.out
    

    GitHubアップストリーム

    これが発生すると、CPUはカーネルがブート時に登録した割り込みコールバックハンドラーを呼び出します。ハンドラを登録して使用する具体的なベアメタルの例を次に示します。

    このハンドラーはリング0で実行され、カーネルがこのアクションを許可するかどうかを決定し、アクションを実行し、リング3でユーザーランドプログラムを再起動します。x86_64

  • ときにexecシステムコールが使用されている(または場合カーネルが開始されます/init)、カーネルは、レジスタおよびメモリ準備し、新しいユーザーランドプロセスのをそれがエントリポイントにジャンプし、リング3にCPUを切り替えます

  • (ページングのため)禁止されたレジスタまたはメモリアドレスへの書き込みなど、プログラムがエッチなことを行おうとすると、CPUはリング0のカーネルコールバックハンドラも呼び出します。

    しかし、ユーザーランドはいたずらだったので、今回はカーネルがプロセスを強制終了するか、シグナルで警告を出す可能性があります。

  • カーネルが起動すると、一定の周波数でハードウェアクロックがセットアップされ、定期的に割り込みが生成されます。

    このハードウェアクロックは、リング0を実行する割り込みを生成し、ウェイクアップするユーザーランドプロセスをスケジュールできるようにします。

    このようにして、プロセスがシステムコールを実行していない場合でも、スケジューリングが行われる可能性があります。

複数のリングを持つことの意味は何ですか?

カーネルとユーザーランドを分離する主な利点は2つあります。

  • どちらか一方が他方に干渉しないことが確実になるため、プログラムの作成が簡単になります。たとえば、あるユーザーランドプロセスは、ページングのために別のプログラムのメモリを上書きしたり、別のプロセスに対してハードウェアを無効な状態にすることを心配する必要はありません。
  • より安全です。たとえば、ファイルのアクセス許可とメモリの分離により、ハッキングアプリが銀行データを読み取ることができなくなる可能性があります。もちろん、これはあなたがカーネルを信頼していることを前提としています。

それをいじるには?

リングを直接操作するのに適したベアメタルセットアップを作成しました。https//github.com/cirosantilli/x86-bare-metal-examples

残念ながら、ユーザーランドの例を作る忍耐力はありませんでしたが、ページングの設定まで行ったので、ユーザーランドは実現可能です。プルリクエストを見たいです。

または、Linuxカーネルモジュールはリング0で実行されるので、それらを使用して特権操作を試すことができます。たとえば、制御レジスターを読み取ります。プログラムから制御レジスターcr0、cr2、cr3にアクセスする方法は?セグメンテーション違反の取得

ここで便利なQEMU + Buildrootセットアップあなたのホストを殺すことなく、それを試しては。

カーネルモジュールの欠点は、他のkthreadが実行中であり、実験に干渉する可能性があることです。しかし理論的には、カーネルモジュールですべての割り込みハンドラーを引き継ぎ、システムを所有することができます。

負のリング

負のリングは実際にはIntelのマニュアルで参照されていませんが、実際にはリング0自体よりもさらに機能を備えたCPUモードが存在するため、「負のリング」の名前に適しています。

1つの例は、仮想化で使用されるハイパーバイザーモードです。

詳細については、以下を参照してください。

ARMでは、リングは代わりに例外レベルと呼ばれますが、主な考え方は同じです。

ARMv8には4つの例外レベルがあり、一般に次のように使用されます。

  • EL0:ユーザーランド

  • EL1:カーネル(ARM用語では「スーパーバイザー」)。

    以前は統一されたアセンブリsvc呼ばれていた命令(SuperVisor Call)を入力します。これは、Linuxシステムコールの作成に使用される命令です。Hello world ARMv8の例:swi

    こんにちは。

    .text
    .global _start
    _start:
        /* write */
        mov x0, 1
        ldr x1, =msg
        ldr x2, =len
        mov x8, 64
        svc 0
    
        /* exit */
        mov x0, 0
        mov x8, 93
        svc 0
    msg:
        .ascii "hello syscall v8\n"
    len = . - msg
    

    GitHubアップストリーム

    Ubuntu 16.04のQEMUでテストします。

    sudo apt-get install qemu-user gcc-arm-linux-gnueabihf
    arm-linux-gnueabihf-as -o hello.o hello.S
    arm-linux-gnueabihf-ld -o hello hello.o
    qemu-arm hello
    

    以下は、SVCハンドラー登録してSVC呼び出しを行う具体的なベアメタルの例です。

  • EL2:ハイパーバイザーXenなど)

    hvc命令(HyperVisor Call)で入力されました。

    ハイパーバイザーはOSに対するものであり、ユーザーランドにとってOSとは何か。

    たとえば、Xenを使用すると、LinuxやWindowsなどの複数のOSを同じシステムで同時に実行でき、Linuxがユーザーランドプログラムと同じように、OSを互いに分離してセキュリティとデバッグを容易にします。

    ハイパーバイザーは、今日のクラウドインフラストラクチャの重要な部分です。ハイパーバイザーは、単一のハードウェア上で複数のサーバーを実行できるようにし、ハードウェアの使用率を常に100%に保ち、大幅なコスト削減を実現します。

    たとえばAWSは、KVMへの移行が発表される2017年までXenを使用していました

  • EL3:さらに別のレベル。TODOの例。

    smc指示で入力(セキュアモードコール)

ARMv8アーキテクチャリファレンスモデルDDI 0487C.a -章D1 - AArch64システムレベルプログラマモデル-図D1-1が美しく、これを示しています。

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

ARMの状況は、ARMv8.1 Virtualization Host Extensions(VHE)の登場により少し変わりました。この拡張機能により、EL2でカーネルを効率的に実行できます。

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

VHEは、KVMなどのLinuxカーネル内の仮想化ソリューションがXenを上回ったために作成されました(たとえば、上記のAWSのKVMへの移行を参照)。ほとんどのクライアントはLinux VMのみを必要とし、想像できるように、すべてが単一のVMであるからです。プロジェクトでは、KVMはXenよりもシンプルで、潜在的に効率的です。そのため、これらの場合、ホストLinuxカーネルがハイパーバイザーとして機能します。

ARMは、後知恵の恩恵により、特権レベルの命名規則がx86よりも優れていることに注意してください。負のレベルは必要ありません。0は最低、3は最高です。高いレベルは、低いレベルよりも頻繁に作成される傾向があります。

現在のELは、次のMRS命令で照会できます。現在の実行モード/例外レベルは何ですか?

ARMでは、チップ領域を節約する機能を必要としない実装を可能にするために、すべての例外レベルが存在する必要はありません。ARMv8の「例外レベル」は次のように述べています。

実装には、すべての例外レベルが含まれていない場合があります。すべての実装にはEL0とEL1を含める必要があります。EL2とEL3はオプションです。

EL1に例のデフォルトのためのQEMUが、EL2とEL3は、コマンドラインオプションを有効にすることができます:A53パワーアップをエミュレートする際のqemu-システムaarch64入るEL1

Ubuntu 18.10でテストされたコードスニペット。


1
この質問は、どのOSに固有ではない、ので、inそしてoutリング3にご利用いただけますTSSは、すべてまたは特定のポートへの読み取り/書き込みアクセスを許可する現在のタスクにIO許可テーブルを指すことができます。
マイケルペッチ2018

もちろん、IOPLビットを値3に設定すると、リング3プログラムは完全なポートアクセスを持ち、TSS IO権限は適用されません。
マイケルペッチ2018

@MichaelPetchありがとう、私はこれを知りませんでした。答えを更新しました。
Ciro Santilli郝海东冠状病六四事件法轮功

5

私は暗闇の中で突き刺すつもりだし、あなたはWindowsについて話していると思います。簡単に言えば、カーネルモードはハードウェアへの完全なアクセス権を持っていますが、ユーザーモードはそうではありません。たとえば、ほとんどのデバイスドライバーは、ハードウェアの詳細を制御する必要があるため、カーネルモードで書かれています。

このウィキブックも参照してください。


2
カーネルのバグは、あなたが慣れているよりもはるかに悪い混乱をもたらす傾向があるため、これはプログラマーにとってあなたにとって重要です。カーネルとユーザーを区別する1つの理由は、カーネルが重要なシステムリソースを監視/制御し、各ユーザーを他のユーザーから保護できるようにするためです。ユーザーのバグはしばしば煩わしいものですが、カーネルのバグはマシン全体をダウンさせる傾向があることを思い出させるには、少し単純化しすぎますが、それでも役に立ちます。
Adam Liss

3

他の回答では、ユーザーモードとカーネルモードの違いが既に説明されています。詳細を知りたい場合は、Windows Internalsのコピーを入手してください。これは 、Mark RussinovichとDavid Solomonによって書かれた、さまざまなWindowsオペレーティングシステムのアーキテクチャと内部の詳細を説明した優れた本です。


2

基本的に、カーネルモードとユーザーモードの違いはOSに依存せず、ハードウェア設計により、一部の命令がカーネルモードでのみ実行されるように制限することによってのみ達成されます。メモリ保護のような他のすべての目的は、その制限によってのみ実行できます。

どうやって

これは、プロセッサがカーネルモードまたはユーザーモードで動作していることを意味します。アーキテクチャは、いくつかのメカニズムを使用して、カーネルモードに切り替えられるたびに、OSコードがフェッチされて実行されることを保証できます。

なぜ

このハードウェアインフラストラクチャがあれば、これらは一般的なOSで実現できます。

  • たとえば、プログラムがOSを上書きしないように、ユーザープログラムをメモリ全体にアクセスしないように保護します。
  • たとえば、プログラムがメモリの境界を壊さないように、CPUメモリポインタの境界を変更するような機密命令をユーザープログラムが実行するのを防ぎます。
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.