5

C プログラムをコンパイルすると、機械が理解できるコードが生成されるだけです。このコードは、この質問からわかるように、ハードウェア上で直接実行できます。

だから私の質問は:

  1. C プログラムをハードウェア上で直接実行できる場合、カーネルはこのプログラムのリソース割り当てをどのように処理できますか?

  2. コンパイラから生成された実行可能ファイルが純粋にマシンが理解できる形式である場合、特権モードと非特権モードはどのように機能するのでしょうか?

  3. プログラムがカーネルを介さずにハードウェア上で直接実行できる場合、カーネルはハードウェア リソースの許可をどのように管理しますか?

4

4 に答える 4

5

Cプログラムがハードウェア上で直接実行できる場合、カーネルはこのプログラムへのリソース割り当てをどのように処理できますか.

カーネルは、ハードウェアなどのリソースを含め、コンピューターのリソース全体を管理する役割を果たします。これは、ユーザーレベルのアプリケーションがハードウェアデバイスなどにアクセスしたり、端末に書き込んだり、ファイルを読み取ったりできるようにするには、カーネルに許可を求める必要があることを意味します。これは、@Marcus で言及されているように、OS によって公開されたシステム コールを使用して行われます。

ただし、カーネルモジュール/ドライバーのようにハードウェアと直接対話しないという意味で、プログラムがハードウェア上で直接実行されるとは言いません。クライアント プログラムは、システム コールの引数を設定し、カーネルに割り込み、プログラムが行った割り込み要求をカーネルが処理するまで待ちます

これが、現在の OS がプロテクト モードで実行されると言われる理由です。以前はリアル モードで実行されていて、プログラムがハードウェア リソースを直接いじったり、システムを台無しにする可能性があったのとは対照的です。

x86 アセンブリで単純な「hello world」プログラムを作成してみると、この違いは非常に明確になります。私はこれを数年前に書き、文書化しました。以下に再現します。

;
; This program runs in 32-bit protected mode.
;  build: nasm -f elf -F stabs name.asm
;  link:  ld -o name name.o
;
; In 64-bit long mode you can use 64-bit registers (e.g. rax instead of eax, rbx instead of ebx, etc.)
; Also change "-f elf " for "-f elf64" in build command.
;
section .data                           ; section for initialized data
str:     db 'Hello world!', 0Ah         ; message string with new-line char at the end (10 decimal)
str_len: equ $ - str                    ; calcs length of string (bytes) by subtracting the str's start address
                                            ; from this address ($ symbol)

section .text                           ; this is the code section
global _start                           ; _start is the entry point and needs global scope to be 'seen' by the
                                            ; linker --equivalent to main() in C/C++
_start:                                 ; definition of _start procedure begins here
    mov eax, 4                   ; specify the sys_write function code (from OS vector table)
    mov ebx, 1                   ; specify file descriptor stdout --in gnu/linux, everything's treated as a file,
                                             ; even hardware devices
    mov ecx, str                 ; move start _address_ of string message to ecx register
    mov edx, str_len             ; move length of message (in bytes)
    int 80h                      ; interrupt kernel to perform the system call we just set up -
                                             ; in gnu/linux services are requested through the kernel
    mov eax, 1                   ; specify sys_exit function code (from OS vector table)
    mov ebx, 0                   ; specify return code for OS (zero tells OS everything went fine)
    int 80h                      ; interrupt kernel to perform system call (to exit)

プログラムが write システム コール を設定し、書き込みsys_write先のファイル記述子、stdout書き込み文字列などを指定する方法に注目してください。

つまり、プログラム自体は書き込み操作を実行しません。それは物事をセットアップし、特別な割り込みを使用して、カーネルに代わってそれを行うように要求しますint 80h.

ここで例えることができるのは、レストランに行くときです。サーバーが注文を受け取りますが、シェフが調理を行います。このアナロジーでは、あなたはユーザーレベルのアプリケーションであり、料理の注文を受けるサーバーはシステム コールであり、キッチンのシェフは OS カーネルです。

gcc から生成された実行可能ファイルが純粋にマシンが理解できる形式である場合、特権モードと非特権モードはどのように機能するのでしょうか?

前のセクションから離れて、ユーザー レベルのプログラムは常にユーザーモードで実行されます。プログラムが何かにアクセスする必要がある場合 (例: ターミナル、ファイルの読み取りなど)、sys_write上記の例のように設定し、カーネルに割り込みで代わりにそれを行うように要求します。割り込みにより、プログラムはカーネルモードになり、カーネルがクライアントの要求の処理を完了するまでそこにとどまります。これには、クライアントの要求を完全に拒否することも含まれます (たとえば、ユーザーが読み取る権限のないファイルを読み取ろうとするなど)。

int 80h内部的には、命令の発行を担当するのはシステム コールです。ユーザーレベルのアプリケーションは、クライアントと OS の間の共通インターフェイスであるシステム コールを参照するだけです。

プログラムがカーネルを介さずにハードウェア上で直接実行できる場合、カーネルはハードウェア リソースの許可をどのように管理しますか?

前の説明に従えば、カーネルがゲートキーパーとして機能し、プログラムが命令を使用してこのゲートを「ノック」することがわかりint 80hます。

于 2015-10-21T17:42:21.910 に答える
5

プログラムは機械語で記述されていますが、独自のメモリ領域内で何かを行うには、syscallsを介してカーネルを呼び出す必要があります。

CPU には、コードの特権という概念があります。特権のないコードは、物理メモリなどに直接アクセスできません。OSを介して、アクセスを許可するように要求する必要があります。

したがって、すべてのプログラムは CPU 上で直接実行されますが、それはハードウェアで何でもできるという意味ではありません。それに対するハードウェア測定があります。特定のことを行うために必要な特権は、これらの 1 つです。

于 2015-10-21T17:09:37.830 に答える
3

カーネルはこのプログラムへのリソース割り当てをどのように処理できますか

カーネルは、ユーザー プログラムへのシステム コールと呼ばれる、メモリの割り当て、I/O (画面への書き込み、ネットワーク/サウンド カードとの対話) などを行うための関数とメカニズムを提供します。これらのシステム コールは、カーネルとユーザー プログラム間のインターフェイスであり、残念ながらハードウェアとユーザー プログラム間のインターフェイスです。

特権モードと非特権モードはどのように機能しますか?

カーネルが特権モード (カーネル空間) で実行されている間、ユーザー プログラムは非特権モード (ユーザー空間) にあります。ユーザーは信頼できないため、失敗した場合 (たとえば、より高い特権のメモリにアクセスしたり、null ポインターを逆参照したり)、(セグメンテーション違反やそれに続くプログラムの終了などによって) それを防ぐことができます。

一方、カーネルは特権モードで実行されます。ユーザー空間プログラムへの書き込み、ユーザー プログラムからのデータ (パスワードなど) の盗み出し、プロセッサのファームウェアへの書き込みなど、何でも実行できます。さらに、さまざまな種類のカーネルがあります。モノリシック カーネルとマイクロカーネルは、最も重い (その言葉は存在しますか?) 使用されるものです。

Linux (Linus Torvalds が開始) は、モノリシック カーネルの例です。ここで、カーネルは 1 つの大きなシステムであり、カーネル コードのすべての部分がシステムに最終的にアクセスできます。

Minix (Andrew S. Tanenbaum によって開始された) は、マイクロカーネルの例です。すべてにアクセスできる部分はかなり小さいです。特権が必要な機能 (MMU の管理、ハードウェアへのアクセス) などのみが含まれます。ファイルシステムなどの他の機能は、ユーザー空間で採用されている通常の保護メカニズム (非特権モード) によって潜在的なバグから保護される非特権モードで実行されます。モード)、セグメンテーション フォールトなど。

モノリシック カーネルとマイクロカーネルの利点/欠点に関する興味深い読み物は、Linus Torvalds (当時 OS を作成した人物) と Andrew S. Tanenbaum (当時 CS の確立された教授であり、いくつかの素晴らしい本を書いている) の間の議論です。 、ところで)。

プログラムは、カーネルを介さずにハードウェア上で直接実行できます

実際、CPU によって実行されるハードウェア上で直接実行されます。ただし、メモリなどの特定のリソースに直接アクセスすることはできず、これらのリソースにアクセスするには、カーネルと対話する必要があります。これは、DOS などの以前の OS に対する主要な改善点の 1 つです (おそらく仮想プロセッサ、つまりプロセスの次に)。ユーザー空間プログラムはハードウェア上で直接実行できません。可能であれば、取り返しのつかない原因でマシン全体を台無しにする可能性があります(意図的に-ウイルスのように、または意図せずに)。代わりに、この回答の冒頭で述べたように、システム コールが使用されます。

DOS では、OS によって提供されるルーチンを使用するオプションがありました (一般に、IV (割り込みベクトル、リアル モード IDT (割り込み記述子テーブル) へのオフセット (および物理メモリ アドレス)) でのトラップ) 0x21 ( int 0x21/経由で呼び出されますint 21h)。axシステムへの呼び出しを識別する関数番号が含まれていました1 )。現在利用可能なメカニズムとほぼ同じですが、厳密には強制されていません。OS全体を上書きし、それを自分のプログラムに置き換えて、マシンを破壊することができます(たとえば、ランダムな値をCMOSレジスタにロードします)。OS をバイパスして、BIOS が提供するルーチンを使用することもできます。


1ここでは意図的に「システムコール」ではなく「システムへの呼び出し」を使用しています。ここで、システム コールは、ユーザー空間からカーネル空間への何かを実行するための要求のみを示します。DOS (つまり、リアル モード) はユーザー空間とカーネル空間を実際に区別していなかったため、実際にはシステム コールがありません。

于 2015-10-21T17:32:03.713 に答える
2

したがって、私の最初の質問は、C プログラムがハードウェア上で直接実行できるかどうか、カーネルがこのプログラムへのリソース割り当てをどのように処理できるかということです。

CPU には、コードを実行する際の特権の概念があります。たとえば、x86 には、コードが任意のリソースにアクセスできるリアル モードと、コードが個別のセキュリティ リングで実行される保護モードがあります。ほとんどのオペレーティング システムは保護モードに切り替わります。保護モードでは、リングの数値が低いほど特権が高くなります。

カーネルは通常、ハードウェアに直接アクセスできるリング 0 で実行されますが、ユーザー プログラムはアクセスを制限するリング 3 で実行されます。ユーザー プログラムが特権リソースにアクセスする必要がある場合、CPU は特権を持つオペレーティング システムを暗黙的に、またはシステム コール命令 ( syscallx86-64 アセンブリなど) を介して直接呼び出します。

gcc から生成された実行可能ファイルが純粋にマシンが理解できる形式である場合、特権モードと非特権モードはどのように機能するのでしょうか?

ここでも、メモリ アクセスなどは CPU によってチェックされます。したがって、たとえば、プログラムが許可されていない仮想アドレスSIGSEGVにアクセスしようとすると、オペレーティング システムは無効なページ アクセスをキャッチし、通常はプロセス (つまり) に通知します。

プログラムがカーネルを介さずにハードウェア上で直接実行できる場合、カーネルはハードウェア リソースの許可をどのように管理しますか?

CPU は、特定の制御レジスタとテーブルを介してオペレーティング システムと直接対話する必要があります。たとえば、仮想アドレス ページ テーブルのアドレスは、CR3x86 のレジスタに格納されます。

于 2015-10-21T17:59:25.547 に答える