ユーザーランドとは何かを正確に理解しようとしていますか?私が尋ねる誰もが言う:「カーネルではないもの」。しかし、それは私には具体的ではありません。私が読んでいるとき、カーネルはそのドライバをユーザーランドなどで実行できます。何が起こるか想像もできない!ですから、この点について誰かが正直に言ってくれれば幸いです。
1つの概念的なレベルでは、カーネルはハードウェア保護の「より特権的な」レベルで実行されるすべてのものです。これは、x86プロセッサのリング0、ARMのシステムモード、MIPSのカーネルモード、68xxxのスーパーバイザモードなどのようになります。カーネルは通常、ソフトウェア駆動(システムコール)またはハードウェア遮断(ディスクドライブ、ネットワーク)カード、ハードウェアタイマー)。
同じ概念レベルで、「ユーザーランド」は、最小特権モード(x86 CPUではリング3、ARMまたはMIPSなど)でユーザーモード)で実行されるものです。ユーザーランドは、カーネルが小さなハードウェアの違いを平滑化し、すべてのプログラムに同じAPIを提示する方法。たとえば、一部のワイヤレスカードは、他のカードに比べて追加の制御レジスタを備えていたり、着信パケット用のオンボードバッファを含んでいる場合があります。ドライバコードはこれらの違いを説明し(場合によっては高度な機能や異常な機能を無視する)、すべてのプログラムに同じソケットAPIを提供します。
一部のプロセッサ(x86、VAX、Alpha AXPなど)には3つ以上のモードがありますが、一般的なUnixアーキテクチャは中間モードを使用しません。
Unix、Linux、または* BSDで実行されているプログラムとプロセスがユーザーランドです。プロセスはプリエンプティブルであるため、実際にはカーネルが実行されることはなく、read()
システムコールが戻る、またはシグナルハンドラー関数が実行されるなどの副作用が発生するだけです。
Unix、Linux、* BSDでの特定の質問に答えるために、「ドライバー」は通常、ハードウェアの特定の特性(ネットワークカード、ディスクドライブ、ビデオカード)を処理する小さなソフトウェアです。ドライバーソフトウェアは、ほとんどの場合、ハードウェア割り込み、またはハードウェアのマップされたメモリなどにアクセスするために、リング0 /スーパーバイザーモード/カーネルスペースで実行する必要があります。ドライバーは特定のハードウェア機能を処理し、そのハードウェアを、ハードウェアがどのように機能するかについてのカーネルコードの標準化されたビューまたは従来のビューに適合させます。したがって、ユーザーランドでドライバーを実行するには、マップされたメモリやデバイスレジスタ、割り込み、その他の特別な機能などのカーネルをユーザーランドプログラムに表示する必要があります。デバイスが必要とする可能性のある特別な機能は、ユーザーの土地プログラムに提示される通常のUnixスタイルのAPIに簡単には適合しないため、これは注意が必要です。また、ユーザーランドプログラムは通常、割り込みにそれほど迅速に応答しないため、スケジューリングが問題になります。
最近のほとんどのCPUには、カーネルまたはスーパーバイザモードと制限付きユーザーモードがあります。これはCPUのハードウェア機能です。 「ユーザーランド」は、ユーザーモードで実行されるコードの別名です。
モード間の1つの大きな違いは、ほとんどの最新のCPUのMMUがそれらの下でどのように動作するかという点です。
MMUは、カーネルがRAMのブロック(またはページ)を再配置できるようにするため、物理的にRAMにあるのとは異なる順序でコーディングされているように見えます。また、特定のページにアクセスした場合、ユーザーモードコードをtrapまたは "fault"に戻してカーネルモードに戻します。ユーザーモードでは、 MMUは、カーネルモードでのみ実行できます。
したがって、MMUを使用すると、カーネルモードのコードで次のようなあらゆる種類の優れた機能を実行できます。
MMUは、カーネル/ユーザーモードと共に、マルチタスクオペレーティングシステムの基礎であり、これらのツールを使用して、プロセスの概念などのより高レベルなもので機能するシステムを作成できます。カーネルは各プロセスのページテーブルを維持し、基本的にMMUを再プログラミングしてから、ユーザーモードに切り替えて、タイムスライスのプロセスを制御します。malloc
のようなものプロセスがメモリを取得している場合、カーネルはMMUページテーブルを変更します。
繰り返しますが、ユーザーモードはページテーブルに対して何も実行できません(実際にそれらが存在することを知る必要はありません)。メモリが必要な場合は、カーネルをcallする必要があります。これにより、ユーザーモードからカーネルモードに切り替わります。 CPUはこれを行うためのソフトウェア割り込みと呼ばれる単純なメカニズムを提供します そしてLinuxカーネルが使用する他の高速な方法があります 。
ユーザーモードに存在するこの保護のため、プログラムがクラッシュしたり、わざわざ行ったりして自分自身を上書きした場合、カーネルはこのプロセスを停止できます。カーネルモードでは、この保護は存在しないため、カーネルが機能しなくなり、システム全体も機能しなくなります。カーネルモードでこのような回復不可能なエラーが発生すると、カーネルパニックと呼ばれます。詳細は 「カーネルパニック」とは? を参照してください。
カーネルはユーザーランドでそのドライバーを実行できます
CPUのカーネルモードまたはスーパーバイザモードでは、ユーザーモードがI/Oデバイスに直接アクセスすることもできません。そのためには、カーネルを呼び出す必要があります。 Linuxでは、デバイスと直接通信する(カーネルモードで実行される)コードはdevice drivers(type ofkernel module、 lsmod
、insmod
、modprobe
、rmmod
)などのコマンドを使用して操作できます。
最も単純な設定でカーネルモードで実行されるデバイスドライバーにバグがあり、RAMでランダムなものを上書きするなどの厄介なことをすると(カーネルモードであるため、すべてのRAMへの無制限のアクセスがあり、カーネル自体を上書きできます。)デバイスモードをユーザーモードで実行して、カーネル自体に何もできない場合は、または他のプロセス。
残念ながら、ユーザーからカーネルモードへの切り替え(コンテキストスイッチと呼ばれます)は、基本的にCPUの状態全体を各プロセスまたはカーネルに対して切り替えて行う必要があるため、遅くなります自体。したがって、安全性と速度の2つが対立しているため、それが競合と設計のポイントです。
ユーザーモードで可能な限り多くのことをしようとするカーネルはmicrokernelsと呼ばれ、Linuxはその逆でありmonolithicと呼ばれます。 Linuxにはユーザーモードドライバーが存在し(例としてFuseを参照)、それを可能にする framework さえあります。
ブルースの発言に基づいて、カーネルに提供されるすべてのコードは信頼されなければなりません。悪意のあるコードがカーネルによって実行される可能性があるとすれば、それはゲームオーバーです。ここで、ユーザーが実行したコードとカーネルが実行したコードの権限分離が機能します。ユーザーが実行するコードは、必ずしも100%悪から解放されている必要はありません。カーネルによって直接実行されることはありません。
ユーザーランドプログラムは、APIや読み込まれたモジュールなど、カーネルの公開された部分と対話するだけです。例はiptables
です。実際にiptables
の機能を実行するカーネルモジュール(.ko)または 'ドライバー'がいくつかあります。これらは netfilter framework の一部です。 /sbin/iptables
を使用してコマンドを実行するときは、カーネルに読み込まれているnetfilterモジュールと通信するユーザーランドコンポーネントを使用しています。これにより分離が可能になり、ユーザーコードがカーネルによって誤って実行されないようにすることができます。
これらの概念を十分に理解する1つの方法は、 osdev.org または James Molloy's Tutorial のようなチュートリアルに参加することです。
Linuxはモノリシックカーネルを備えています。これは、Bruceが述べたように、x86アーキテクチャではそのコードが完全にリング0で実行されることを意味します。したがって、カーネルはすべてのリソースを完全に制御できるため、ユーザーレベルのアプリケーション(最低特権レベル3で実行)によるそれらのすべての要求を管理します。
このことを考えてみてください。ユーザー空間のアプリケーションが仮想メモリにフルアクセスできる場合-RAM-他のプロセスのスタックまたはヒープからカーネルの内部バッファに至るまで、すべてを破棄する可能性があります。カーネルはページをそれぞれにマップしますプロセスのページディレクトリ、およびアプリケーションがそのアドレススペースに属していない場所にアクセスしようとして誤動作した場合、アプリケーションは強制的にシャットダウンされます。
次に、各プログラムがプリンターまたは他の出力デバイスに直接アクセスする場合はどうなるかを考えます。プリンターに印刷しようとするプロセスの2つの同時インスタンスはすべてをスクランブルしますが、これらの要求がカーネルを通過する場合、それらはキューに入れられて別々に処理され、結果として2つの別々の印刷ページになります。
さらに、マシンは通常、現在実行中のプロセスよりもプロセッサの数が少ないため、カーネルはスケジューラを使用してプロセスを切り替え、それぞれが独自の有限時間でプロセッサを使用します。この時間が経過すると、アクティブなプロセスのリストの最後、または非アクティブなプロセスのリストに移動されます(プロセスがデバイスからのデータを待っている場合)。このようにして、すべてのプロセスは同時に実行されているように見えますが、1つのプロセスのみ、またはカーネルが常に1つのプロセッサを使用するようになります。この概念は、疑似並列処理と呼ばれます。
ユーザーランドのドライバーに関する最後の質問について:これは可能ですが、カーネルはデバイスとの通信を完全に制御し続けます。たとえば、カーネルはカーネルメモリの領域をユーザー空間ドライバのメモリ領域にマップし、デバイスメモリへのアクセスを許可します。カーネルは、変更をデバイスに転送するかどうかをまだ持っています。このユーザーランドドライバーは、他のユーザーアプリケーションに対してデバイスを制御するための素敵なインターフェイスを提供します。ドライバーがクラッシュした場合でも、マシンをリセットせずにドライバーを再ロードできる可能性があります。ドライバーがカーネルスペースにある場合(モジュールなど)、モジュールがスタックしてアンロードできない場合は、シンボルが既に存在するため再ロードできません。そのため、唯一のチャンスは、機械。
結論として、cat topや "hello world"などのアプリケーションはユーザー空間でのみ実行され、システムコールと呼ばれる関数のセットであるカーネルAPIを介してのみシステムのリソースにアクセスできます。したがって、アプリケーションがread()システムコールを発行してファイルから読み取ると、カーネルがプロセッサを制御し、適切なドライバー(HDDドライバーなど)を使用してデータを読み取り、このデータを、 read()システムコールに渡されるポインター。このデータが利用可能になるとすぐにアプリケーションが実行を継続できるようにします。
あなたはすでにいくつかの良い答えを得ましたが、私は短くて簡潔な答えにも価値があると思います:
最近のCPUでは、特定のコードが実行できることを制限できます。 「カーネルモード」とは、ハードウェアへのフルアクセスが可能な制限のないコードを指します。 「ユーザーランド」は、権限が制限されたコードです。ユーザーランドコードが独自のメモリ以外にアクセスする場合は、カーネルを呼び出す必要があります。カーネルは、要求されたアクションを実行する前に権限を確認します。
Unix/Linuxオペレーティングシステムでは、ser spaceとkernel spaceは異なります。これは、ユーザーランドの同義語であり、カーネルが属する場所です。
次のように理解できます。ユーザースペースで行われているすべての操作を行うことができます。カーネル空間ではそうではありません。デーモン、ライブラリ、およびアプリケーションは、ユーザースペースに属します。オペレーティングシステムのカーネルの外部で実行されるすべてのコードは、ユーザー空間(ユーザーランド)に属します。
カーネル空間は、カーネル自体が実行される場所です。これは、ルートでさえアクセスできない制限された領域です。しかし、rootユーザーは、カーネル(procfs、sysfs)によって提供されるインターフェースによって、いくつかのカーネルパラメーターを操作できます。
システムメモリは、カーネルとユーザー空間の違いを説明する良い例です。デーモン(ユーザー空間で実行される)を実行するには、ある程度のメモリが必要です。カーネルは、利用可能なすべてのメモリを管理します。デーモンはカーネルからいくらかの「仮想メモリ」を取得します。デーモンは、それが物理メモリであるか、スワップ領域であるかなどを認識していません。カーネルは、プロセスが取得するメモリの種類を決定するものです。なぜなら、メモリ管理はカーネル空間で行われるからです。カーネル空間で発生する他のことは、プロセスのスケジューリング、プロセス間の通信、メモリの保護と管理、システムコールです...
ユーザーランドとは正確には何ですか?
したがって、ユーザーランドは、オペレーティングシステムリソース(I/O、ネットワーク、メモリ、CPU時間)と対話するときにデーモンが実行する(または実行できる)ことです。これらのリソースは、カーネル空間のプロセスから隠されています。
短い答え:
パイロット用の飛行機のコックピットはそれです。
最初に私はここに多くの素晴らしい答えがあることに同意します。
私の貢献は、Linuxシステム管理の本「カーネル:OSのメモリ常駐部分」でカーネルについて数年前に見つけた最も短い定義です。