OSがCPUと直接連携している場合、OSはプログラムの機能をどのように制限しますか?
プログラムがメモリにロードされて実行を開始すると、cpuはコードから各命令をロードし、オペコードと引数に基づいて命令を実行するため、プログラムは、いわばcpuに対して直接対話します。
ただし、OS(linux / win)ではすべてを実行できるわけではないため、システムコールを使用して、いくつかのことを許可する必要があります。しかし、ユーザーコードがOSが実行できる特定のことを実行できないのはどういうことなのか、OSカーネルコードがコマンドを実行するかどうか、またはユーザーが実行するかどうかによって、CPUにどのような違いが生じるのでしょうか。
OSはコードをロードする前にコードを調べて、使用が許可されていない特定の命令を使用しているかどうかを確認しますか?使用している場合は、単に実行しませんか?
それはどのように管理されていますか?
ところで、アセンブリをプログラミング言語と見なしているため、プログラマーはコードで使用する任意の命令を選択できます。
回答
最近のCPUには、オペレーティングシステムが特定の命令をロックアウトするために使用する特権モードがあります。たとえば、user
モードでは、特権モードを変更(引き上げ)したり、現在構成されているページテーブルなどのシステムリソースにアクセスしたりする命令によって例外が発生します。これにより、オペレーティングシステムは、ユーザープロセスを中止するか、操作をエミュレートするかを決定できます。
OSはコードをロードする前にコードを調べて、使用が許可されていない特定の命令を使用しているかどうかを確認しますか?使用している場合は、単に実行しませんか?
いいえ、その必要はありません。オペレーティングシステムは、ユーザーコードを実行するたびに、プロセッサを「ユーザー」モードにします。これにより、特権命令が発生した場合にハードウェアの例外メカニズムがアクティブになります。ユーザーモードでは、特権命令を実行する代わりに例外が発生します(例外のトリガーは、特権操作ではなく、その命令の実行です)。
ところで、オペレーティングシステムからサービスを要求するためにユーザーモードコードによって使用される命令のシステムコールタイプも、ハードウェア例外メカニズムをアクティブにします。
それはどのように管理されていますか?
オペレーティングシステムは常にユーザーモード(ユーザーレベルの特権)でユーザーコードを実行し、通常はより高い特権で独自のコードを実行します。これらのモードは、特権命令の処理方法をプロセッサに通知します。ほとんどのユーザーモードコードは、特権命令が役に立たないため、実行しようとさえしませんが、実行すると、ハードウェア例外メカニズムが作動し、これが発生したことをオペレーティングシステムに効果的に通知し、状況を処理できるようにします。
ユーザーモードコードを実行するために、オペレーティングシステムは「割り込みからの復帰」命令を使用してユーザーコードを再起動する場合があります(技術的に開始されているかどうかは関係ありません)。割り込みからの復帰は、特権レベルを変更すると同時に、命令ストリーム(別名分岐)を変更する1つの方法である命令の一種です。このような命令自体には特権があります。つまり、プロセッサはユーザーモードでの命令を許可しません。
プロセッサが割り込みを取得すると、重要なCPU状態の一部を記録します。重要なCPU状態は、割り込みを処理するために必ず変更する必要がある状態です。割り込みを処理すると、プログラムカウンタ(別名命令ポインタ)を変更することにより、命令ストリームフィードの制御がCPUに転送されます。割り込み時に、プロセッサは効果的に割り込みサービスルーチンに突然分岐します。また、モードが突然より高い特権に変更され、ISRがより多くの命令にアクセスできるようになります。ISRをアクティブ化するには、これら2つの突然の変更が必要なため、ハードウェアは、中断されたユーザーモードコードを再開するときに後で使用するソフトウェアの以前の値を記録します。したがって、ハードウェアとオペレーティングシステムが共謀して、OSを高い特権で実行し、ユーザーコードを低い特権で実行します。
ユーザーモードプログラムがsyscallタイプの命令(I / Oなどのオペレーティングシステムサービスを要求する)を使用する場合、同じハードウェア例外メカニズムが制御をISRに転送します。オペレーティングシステムがユーザーモードプロセスを再開する場合、ハードウェアによっては、再開する前に、syscall命令全体でユーザーモードプロセスのプログラムカウンタを手動で進める必要がある場合があります。これは、ユーザーモードプロセスに対して、オペレーティングシステムは、システムコールをシミュレート/エミュレートしました。
さらに、プログラムのすべてのCPU命令は、独自の仮想メモリ空間で実行されます。これにより、基本的に、システムデータ、他のプロセスデータ、またはカーネルデータにアクセスまたは変更するためにコーディングするすべての命令が無効になります。
基本的には、家を好きなように台無しにすることはできますが、他人の家を調べることはできません。
アドレス空間の外で何かを実行したい場合は、それを実行するシステムルーチン/サービスを呼び出す以外に選択肢はありません。それらはプロセスの承認/特権をチェックします。
上の図にとどまり、他の人の家で何かをしたい場合は、信頼できるサービス、つまりOSカーネルルーチンを使用する必要があります。
この回答は、特定のハードウェアをサポートするプロセッサ(ARM、x86、PowerPCなど)で最新のマルチタスクオペレーティングシステム(Windows、MacOS、Linuxなど)を実行していることを前提としています。これは、ErikEidtとAganjuによる以前の回答を利用しています。
これらのシステムは、通常のユーザープログラムに対してますます制限的になるように長年にわたって開発されてきました。
このようなマシンでは、プログラムは物理メモリに直接アクセスできません。すべてのメモリアドレスは、仮想メモリマネージャを経由します。特定のアドレスがアドレス空間に割り当てられている場合、そのアドレスは物理メモリアドレスにマップされます。そうでない場合、アクセスは失敗し、トラップが生成されます。オペレーティングシステムはおそらくプログラムを終了します。メモリマネージャは、プロセスが別のプロセスのメモリを破壊できないようにします。
ハードウェアデバイスは通常、メモリマップされます。この場合も、メモリマネージャはそれらへの直接アクセスをブロックします。あなたはあなたのためにそれをするためにドライバーを呼ばなければなりません。
オペレーティングシステムがすべてをセットアップし、デバイスドライバを実装するために使用する特別なマシンコード命令があります。これらの命令には、それらを実行するために必要なさまざまな特権レベルがあります。プログラムが起動されると、オペレーティングシステムによって、最も低い特権を持つユーザープログラムとしてマークされます。したがって、これらの命令を使用してメモリ管理を変更またはバイパスしようとすると、トラップされます。繰り返しますが、プログラムは終了する可能性があります。