システムコール
出典: フリー百科事典『ウィキペディア(Wikipedia)』
システムコールとは、オペレーティングシステム (OS)(より明確に言えばOSのカーネル)の機能を呼び出すために使用される機構のこと。実際のプログラミングにおいては、OSの機能は関数 (API) 呼び出しによって実現されるので、OSの備える関数 (API) のことを指すこともある。なお、μITRONではサービスコールと呼ばれる。また、OSのことをスーパーバイザとも呼ぶため、スーパーバイザコールともいう。
例えば、C言語で使用できるfopen()やmalloc()などのライブラリ関数は、その関数内においてシステムコール(例えばPOSIX準拠のOSであればopen()やsbrk()など)を呼び出す。
目次 |
[編集] 背景
現代のプロセッサは一般にいくつかの特権状態で命令を実行する。2つのレベルを持つシステムでは、これを通常ユーザーモードとスーパーバイザーモードと呼ぶ。このような特権レベルがあるのは、セキュリティと安定性を保つためにオペレーティングシステムがその管理下で動作するプログラムによる操作を制限できるようにするためである。そのような制限を受ける操作としては、ハードウェア機器へのアクセス、割り込みの可/不可の変更、プロセッサの特権状態の変更、メモリ管理ユニットへのアクセスなどがある。オペレーティングシステムのカーネルはスーパーバイザーモードで動作し、ユーザーアプリケーションはユーザーモードで動作する。
このような複数の特権レベルを持つシステムを開発するにあたって、低い特権レベルから高い特権レベルへ制御を安全に転送する機構が必要となった。低い特権レベルのコードが単純に高い特権レベルに移行したのではセキュリティと安定性は保てない。例えば、低い特権レベルのコードが高い特権レベルのコードに間違った処理をさせたり、不正なコールスタックを渡すかもしれない。
[編集] 機構
システムコールは、多くの場合、ソフトウェア割り込みによって実行される。ソフトウェア割り込みを用いてCPUの動作モードを遷移させることによって、通常のアプリケーションプログラムからはアクセスできない保護されたメモリ領域にアクセスすることや、保護されたレジスタを操作すること、また、自らCPUの動作モードを変更することなどが可能になる。
システムコールは特殊な命令を使うことが多く、それによってCPUは高い特権レベルのコードに制御を渡す。具体的な方法はシステムに依存するが、例外や割り込みを発生することで高い特権レベルに移行したり、特殊な分岐命令で高い特権レベルに移行したりする。このときにシステムコールの種別を示す番号や引数がレジスタやコールスタックに格納されていて、高い特権レベルのコード(カーネル)がそれを使用して処理を行う。
システムコールが呼び出されたとき、呼び出したプログラムは中断され、後で処理を続行するために必要な情報(コンテキスト)が保存される。そしてプロセッサが高い特権レベルのコードを実行し、上述のシステムコールの番号や引数を調べ、必要な処理を行う。この際に呼び出し側のアクセス権なども考慮して指定されたシステムコールを実行する権利があるかどうかがチェックされる。完了すると呼び出し側プログラムに復帰するため、保存されていた状態情報をリストアし、プログラムの処理が続行される。このとき所定のレジスタ(あるいはスタックの所定の位置)にリターン値が設定される。
多くの場合、プログラムへの復帰が即座に行われない可能性があることに注意が必要である。システムコールでは時間のかかるI/O処理をすることがあり(例えばディスクやネットワークへのアクセス)、プログラムは中断され(「ブロック」状態)、その処理が完了するまで「実行可能」キューに置かれる。必要な処理が完了すると、オペレーティングシステムはそれを実行の候補として扱う。
[編集] 中間層としてのライブラリ
一般にオペレーティングシステムはユーザープログラムとオペレーティングシステムの中間に位置するライブラリを提供している。標準Cライブラリを実装したもの(あるいは同等の機能をもつもの)が多い。このライブラリ内で実際のシステムコール(カーネルへ渡す情報の設定や特権モードへの移行)が行われたり、特権レベルの処理を必要としない様々なデータ処理が行われる。これにより、オペレーティングシステムとアプリケーションの繋がりが緩められ、アプリケーションの移植性が高まっていると言える。特にダイナミックリンクライブラリ (.dll) であれば、システムコール処理部分が実行時にリンクされるため、アプリケーションの実行ファイルをそのまま他のオペレーティングシステム上で実行できる可能性が高まる。
Exokernelに基づいたシステムでは、ライブラリが特に重要である。Exokernelは非常に低いレベルのカーネルAPIしか提供せず、LibOSと呼ばれるライブラリが抽象化やリソース管理の機能を提供している。
[編集] システムコールの例
POSIXおよび類似のシステムでの主要なシステムコールとしては、open、read、write、close、wait、execve、fork、kill などがある。最近のオペレーティングシステムは数百のシステムコールを持つ。例えば、Linuxは約300種類のシステムコールを持つし、FreeBSDも同様(約330)である。