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
ます。