システムコール
システムコール(英: system call)とは、オペレーティングシステム (OS) の機能(より明確に言えばOSのカーネルの特権的な機能)を呼び出すために使用される機構のこと[1]。実際のプログラミングにおいては、OS機能の利用はAPIとして公開されている特別な関数の呼び出しによって実現されるので、OSの備えるAPI関数のことを指すこともある。なお、μITRONではサービスコールと呼ばれる。また、OSのことをスーパーバイザとも呼ぶため、スーパーバイザコールともいう。
例えば、C言語で使用できるfopen()やmalloc()などの標準ライブラリ関数は、その関数内においてシステムコール(例えばPOSIX準拠のOSであればopen()やsbrk()など)を呼び出す。システムコールは一般的なアプリケーションソフトウェアから直接呼び出すことができる(APIとして公開されている)ものもあれば、システムソフトウェアやデバイスドライバーからのみ利用できるようになっているものもある。
日本語では「システム呼び出し」または「システム呼出し」と直訳されることもある[2][3][4]が、この訳語を使って英語のinvoke a system callを訳すと「システム呼び出しを呼び出す」となってしまう。「システム呼び出しを起動する」と訳すこともできるが、一般的には外来語カナ表記である「システムコール」が使われることのほうが多い。
背景
[編集]現代のプロセッサは一般にいくつかの特権状態で命令を実行する。2つのレベルを持つシステムでは、これを通常ユーザーモードとスーパーバイザーモードと呼ぶ。このような特権レベルがあるのは、セキュリティと安定性を保つためにオペレーティングシステムがその管理下で動作するプログラムによる操作を制限できるようにするためである。そのような制限を受ける操作としては、ハードウェア機器へのアクセス、割り込みの可/不可の変更、プロセッサの特権状態の変更、メモリ管理ユニットへのアクセスなどがある。オペレーティングシステムのカーネルはスーパーバイザーモードで動作し、ユーザーアプリケーションはユーザーモードで動作する。
このような複数の特権レベルを持つシステムを開発するにあたって、低い特権レベルから高い特権レベルへ制御を安全に転送する機構が必要となった。低い特権レベルのコードが単純に高い特権レベルに移行したのではセキュリティと安定性は保てない。例えば、低い特権レベルのコードが高い特権レベルのコードに間違った処理をさせたり、不正なコールスタックを渡したりするかもしれない。
機構
[編集]システムコールは、多くの場合、専用命令(インテルx86はPentium II以降、ARMは最初から)もしくはソフトウェア割り込みによって実行される。CPUの動作モードを遷移させることによって、通常のアプリケーションプログラムからはアクセスできない保護されたメモリ領域にアクセスすることや、保護されたレジスタを操作すること、また、自らCPUの動作モードを変更することなどが可能になる。
システムコールは特殊な命令を使うことが多く、それによってCPUは高い特権レベルのコードに制御を渡す。具体的な方法はシステムに依存するが、例外や割り込みを発生させることで高い特権レベルに移行したり、特殊な分岐命令で高い特権レベルに移行したりする。このときにシステムコールの種別を示す番号や引数がレジスタやコールスタックに格納されていて、高い特権レベルのコード(カーネル)がそれを使用して処理を行う。
システムコールが呼び出されたとき、呼び出したプログラムは中断され、後で処理を続行するために必要な情報(コンテキスト)が保存される。そしてプロセッサが高い特権レベルのコードを実行し、上述のシステムコールの番号や引数を調べ、必要な処理を行う。この際に呼び出し側のアクセス権なども考慮して指定されたシステムコールを実行する権利があるかどうかがチェックされる。完了すると呼び出し側プログラムに復帰するため、保存されていた状態情報をリストアし、プログラムの処理が続行される。このとき所定のレジスタ(あるいはスタックの所定の位置)にリターン値が設定される。
多くの場合、プログラムへの復帰が即座に行われない可能性があることに注意が必要である。システムコールでは時間のかかるI/O処理をすることがあり(例えばディスクやネットワークへのアクセス)、プログラムは中断され(「ブロック」状態)、その処理が完了するまで「実行可能」キューに置かれる。必要な処理が完了すると、オペレーティングシステムはそれを実行の候補として扱う。
中間層としてのライブラリ
[編集]一般にオペレーティングシステムはユーザープログラムとオペレーティングシステムの中間に位置するライブラリを提供している。標準Cライブラリを実装したもの(あるいは同等の機能をもつもの)が多い。このライブラリ内で実際のシステムコール(カーネルへ渡す情報の設定や特権モードへの移行)が行われたり、特権レベルの処理を必要としない様々なデータ処理が行われたりする。これにより、オペレーティングシステムとアプリケーションの繋がりが緩められ、アプリケーションの移植性が高まっていると言える。特にダイナミックリンクライブラリ (.dll) であれば、システムコール処理部分が実行時にリンクされるため、アプリケーションの実行ファイルをそのまま他のオペレーティングシステム上で実行できる可能性が高まる。
Exokernelに基づいたシステムでは、ライブラリが特に重要である。Exokernelは非常に低いレベルのカーネルAPIしか提供せず、LibOSと呼ばれるライブラリが抽象化やリソース管理の機能を提供している。
システムコールの例
[編集]POSIXおよび類似のシステムでの主要なシステムコールとしては、open、read、write、close、wait、execve、fork、kill などがある。ファイルシステム・ネットワーク・メモリ・プロセス・スレッド・セキュリティなどの機能を提供している。最近[いつ?]のオペレーティングシステムは数百のシステムコールを持つ。例えば、Linuxは317個(Linux 2.6.35.4現在, i386アーキテクチャ[5][6])、FreeBSDは約500個[7]である。
Microsoft Windowsの場合はWindows APIがシステムコールに相当する。
出典
[編集]- ^ システムコール(スーパーバイザコール / SVC)とは - IT用語辞典 e-Words
- ^ “2.7.6 演習: ユーザーによって実行されるプロセスのトレース”. Oracle. 2019年8月18日閲覧。[リンク切れ]
- ^ カート オール 著、野村 純子 訳「II, 6 システム呼出し」『例題で学ぶLinuxプログラミング』桑村 潤(1版)、ピアソン・エデュケーション、2001年5月20日(原著1999年12月3日)。ISBN 4-89471-2865。
- ^ シルバーシャッツ アブラハム、ガルビン ピーター ベール、ガニエ グレッグ「I, 2.3 システム呼出し」『オペレーティングシステムの概念』土居 範久(監訳)・大谷 真・加藤 和彦・光来 健一・清水 謙多郎・高田 眞吾・高田 広章・千葉 滋・野口 健一郎(訳)(1版)、共立出版、2010年11月。ISBN 978-4-320-12253-6。
- ^ Linux Systemcall Reference
- ^ linux/include/uapi/asm-generic/unistd.h - torvalds/linux - GitHub
- ^ “FreeBSD syscalls.c, the list of syscall names and IDs”. 2013年3月24日閲覧。