システムコール

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ

さまざまなコンポーネントとユーザースペース間の通信を処理するLinuxカーネルのシステムコールインターフェイスの概要

コンピューティングでは、システムコール(通常はsyscallと略されます)は、コンピュータプログラムが実行されるオペレーティングシステムカーネルからサービスを要求するプログラム的な方法です。これには、ハードウェア関連サービス(たとえば、ハードディスクドライブへのアクセスやデバイスのカメラへのアクセス)、新しいプロセスの作成と実行、およびプロセススケジューリングなどの統合カーネルサービスとの通信が含まれる場合があります。システムコールは、プロセスとオペレーティングシステム間の重要なインターフェイスを提供します。

ほとんどのシステムでは、システムコールはユーザースペースプロセスからのみ行うことができますが、一部のシステム、たとえばOS / 360以降では、特権システムコードもシステムコールを発行します。[1]

特権

一部の組み込みシステムを除いて、ほとんどの最新のプロセッサアーキテクチャには、セキュリティモデルが含まれています。たとえば、ringsモデルは、ソフトウェアを実行できる複数の特権レベルを指定します。プログラムは通常、他の実行中のプログラムやオペレーティングシステム自体にアクセスしたり変更したりできないように、独自のアドレススペースに制限され、通常は直接操作できません。ハードウェアデバイス(フレームバッファネットワークデバイスなど)。

ただし、多くのアプリケーションはこれらのコンポーネントにアクセスする必要があるため、オペレーティングシステムによってシステムコールが利用可能になり、そのような操作に対して明確に定義された安全な実装が提供されます。オペレーティングシステムは最高レベルの特権で実行され、アプリケーションがシステムコールを介してサービスを要求できるようにします。システムコールは、多くの場合、割り込みを介して開始されます。割り込みにより、CPUは自動的に昇格された特権レベルになり、カーネルに制御が渡されます。カーネルは、呼び出し元のプログラムに要求されたサービスを許可するかどうかを決定します。サービスが許可されると、カーネルは、呼び出し側プログラムが直接制御できない特定の一連の命令を実行し、特権レベルを呼び出し側プログラムの特権レベルに戻し、制御を呼び出し側プログラムに戻します。

仲介者としての図書館

通常、システムは、通常のプログラムとオペレーティングシステムの間にあるライブラリまたはAPIを提供します。Unixのようなシステムでは、そのAPIは通常、システムコールのラッパー関数を提供するglibcなどのCライブラリ(libc)の実装の一部であり、多くの場合、それらが呼び出すシステムコールと同じ名前が付けられます。Windows NTでは、そのAPIはntdll.dllライブラリのネイティブAPIの一部です。これは、通常のWindowsAPIの実装で使用されるドキュメント化されていないAPIですWindows上の一部のシステムプログラムによって直接使用されます。ライブラリのラッパー関数は、システムコールを使用するための通常の関数呼び出し規約アセンブリレベルでのサブルーチン呼び出し)を公開し、システムコールをよりモジュール化したものにします。ここで、ラッパーの主な機能は、システムコールに渡されるすべての引数を適切なプロセッサレジスタ(および場合によってはコールスタックにも)に配置し、カーネルが呼び出す一意のシステムコール番号を設定することです。 。このように、OSとアプリケーションの間に存在するライブラリは移植性を高めます。

ライブラリ関数自体の呼び出しはカーネルモードへの切り替えを引き起こさず、通常は通常のサブルーチン呼び出しです(たとえば、一部の命令セットアーキテクチャ(ISA)で「CALL」アセンブリ命令を使用)。実際のシステムコールは、カーネルに制御を移します(そして、それを抽象化するライブラリコールよりも実装とプラットフォームに依存します)。たとえば、Unixライクなシステムでは、forkおよびはCライブラリ関数であり、およびシステムコールexecveを呼び出す命令を実行します。アプリケーションコードで直接システムコールを行うことはより複雑であり、埋め込まれたアセンブリコードを使用する必要がある場合があります(CでforkexecおよびC ++)、およびシステムコール操作のための低レベルのバイナリインターフェイスの知識が必要です。これは、時間の経過とともに変更される可能性があるため、アプリケーションのバイナリインターフェイスの一部ではありません。ライブラリ関数は、これを抽象化することを目的としています。

エクソカーネルベースのシステムでは、ライブラリは仲介者として特に重要です。エクソカーネルでは、ライブラリはユーザーアプリケーションを非常に低レベルのカーネルAPIから保護し、抽象化リソース管理 を提供します。

IBMのOS / 360およびDOS / 360は、アセンブリ言語マクロのライブラリを介してほとんどのシステムコールを実装しますが、[a]コールリンケージを備えたサービスがいくつかあります。これは、アセンブリ言語でのプログラミングが高級言語の使用よりも一般的だった時代の起源を反映しています。したがって、IBMシステムコールは、高級言語プログラムによって直接実行可能ではありませんでしたが、呼び出し可能なアセンブリ言語ラッパーサブルーチンが必要でした。それ以来、IBMは、 z / OSz / VSEなどの高級言語から呼び出すことができる多くのサービスを追加してきました

例とツール

UnixUnixライク、およびその他のPOSIX準拠のオペレーティングシステムopen、一般システムコールは、、、、、、、、、、およびです最新のオペレーティングシステムの多くには、何百ものシステムコールがあります。たとえば、LinuxOpenBSDにはそれぞれ300以上の異なる呼び出しがあり、[2] [3] NetBSDには500に近く、[4] FreeBSDには500以上、[5] Windowsには2000に近く、win32k(グラフィカル)とntdllに分けられます(コア)システムは[6]を呼び出しますが、プラン9は51です。[7]readwriteclosewaitexecforkexitkill

straceftracetrussなどのツールを使用すると、プロセスを最初から実行して、プロセスが呼び出すすべてのシステムコールを報告できます。または、操作が権限に違反していない場合は、すでに実行中のプロセスに接続して、そのプロセスによって行われたシステムコールをインターセプトできます。ユーザーの。プログラムのこの特別な機能は、通常、ptraceなどのシステムコールやprocfs内のファイルに対するシステムコールでも実装されます

典型的な実装

システムコールを実装するには、ユーザースペースからカーネルスペースに制御を移す必要があります。これには、ある種のアーキテクチャ固有の機能が含まれます。これを実装する一般的な方法は、ソフトウェア割り込みまたはトラップを使用することです。割り込みはオペレーティングシステムカーネルに制御を移すので、ソフトウェアは必要なシステムコール番号でレジスタを設定し、ソフトウェア割り込みを実行するだけです。

これは多くのRISCプロセッサに提供されている唯一の技術ですが、 x86などのCISCアーキテクチャは追加の技術をサポートしています。たとえば、x86命令セットには命令//が含まれています(これらの2つのメカニズムはそれぞれAMDIntelによって独立して作成されましたが、本質的には同じことを行います)。これらは「高速」制御転送命令であり、割り込みのオーバーヘッドなしにシステムコールの制御をカーネルにすばやく転送するように設計されています。[8] Linux 2.5は、利用可能な場合、x86でこれを使用し始めました。以前は使用していましたSYSCALLSYSRETSYSENTERSYSEXIT INT命令。割り込み0x80が実行されるにシステムコール番号がEAX レジスタに配置されました。[9] [10]

古いメカニズムはコールゲートです。もともとMulticsで使用されていましたが、たとえば、Intelx86のコールゲートを参照くださいこれにより、プログラムは、オペレーティングシステムが事前に設定した安全な制御転送メカニズムを使用してカーネル関数を直接呼び出すことができます。このアプローチは、おそらくx86メモリセグメンテーションを使用するfar呼び出し(現在のコードセグメント[11]とは異なるセグメントにあるプロシージャへの呼び出し)の要件と、その結果として生じる移植性の欠如のために、x86では人気がありませでした。、および上記のより高速な命令の存在。

IA-64アーキテクチャの場合、EPC特権コードの入力)命令が使用されます。最初の8つのシステムコール引数はレジスタに渡され、残りはスタックに渡されます。

IBM System / 360メインフレーム・ファミリーおよびその後継では、レジスターではなく命令に番号が含まれるスーパーバイザー・コール命令SVC )が、 [b] IBM独自のオペレーティング・システムのほとんどでレガシー機能のシステムコールを実装します。 、およびLinuxのすべてのシステムコール。MVSのそれ以降のバージョンでは、IBMは多くの新しい機能に対してプログラム呼び出し(PC)命令を使用します。特に、PCは、発信者がサービスリクエストブロック(SRB)モードになっている可能性がある場合に使用されます。

PDP-11 ミニコンピューターはEMTおよびIOT命令を使用しました。これらは、IBM System / 360SVCおよびx86INTと同様に命令コードを配置します。特定のアドレスに割り込みを生成し、オペレーティングシステムに制御を移します。PDP-11シリーズの後継のVAX32ビットは、CHMK、CHME、およびCHMS命令を使用さまざまレベル特権コードへのシステムコールを行いました。コードは命令の引数です。

システムコールのカテゴリ

システムコールは、大きく6つのカテゴリに分類できます。[12]

  1. プロセス制御
  2. ファイル管理
    • ファイルの作成、ファイルの削除
    • 開閉
    • 読み取り、書き込み、再配置
    • ファイル属性の取得/設定
  3. 端末管理
    • デバイスを要求し、デバイスを解放します
    • 読み取り、書き込み、再配置
    • デバイス属性の取得/設定
    • デバイスを論理的に接続または切り離します
  4. 情報のメンテナンス
    • システム全体の情報(時刻、日付、コンピューター名、企業などを含む)を取得/設定します
    • プロセス、ファイル、またはデバイスのメタデータ(作成者、オープナー、作成日時などを含む)を取得/設定します
  5. コミュニケーション
    • 通信接続の作成、削除
    • メッセージを送信、受信する
    • 転送ステータス情報
    • リモートデバイスの接続または切断
  6. 保護
    • ファイルのアクセス許可を取得/設定する

プロセッサモードとコンテキストスイッチ

ほとんどのUnixライクなシステムのシステムコールは、カーネルモードで処理されます。これは、プロセッサの実行モードをより特権的なモードに変更することで実現されますが、プロセス コンテキストの切り替えは必要ありません。ただし、特権のコンテキストスイッチは発生します。ハードウェアは、プロセッサステータスレジスタに従って実行モードの観点から世界を認識し、プロセスはオペレーティングシステムによって提供される抽象化です。システムコールは通常、別のプロセスへのコンテキストスイッチを必要としません。代わりに、それを呼び出したプロセスのコンテキストで処理されます。[13] [14]

マルチスレッドプロセスでは、システムコールは複数のスレッドから行うことができますこのような呼び出しの処理は、特定のオペレーティングシステムカーネルとアプリケーションランタイム環境の設計に依存します。次のリストは、一般的なモデルとそれに続くオペレーティングシステムを示しています。[15] [16]

  • 多対1モデル:プロセス内の任意のユーザースレッドからのすべてのシステムコールは、単一のカーネルレベルのスレッドによって処理されます。このモデルには重大な欠点があります。ブロッキングシステムコール(ユーザーからの入力を待つなど)は、他のすべてのスレッドをフリーズさせる可能性があります。また、一度に1つのスレッドのみがカーネルにアクセスできるため、このモデルはプロセッサの複数のコアを利用できません。
  • 1対1モデル:すべてのユーザースレッドは、システムコール中に個別のカーネルレベルのスレッドに接続されます。このモデルは、システムコールをブロックするという上記の問題を解決します。これは、すべての主要なLinuxディストリビューションmacOSiOS、最近のWindowsおよびSolarisバージョンに含まれています。
  • 多対多モデル:このモデルでは、ユーザースレッドのプールがカーネルスレッドのプールにマップされます。ユーザースレッドプールからのすべてのシステムコールは、対応するカーネルスレッドプール内のスレッドによって処理されます。
  • ハイブリッドモデル:このモデルは、カーネルの選択に応じて、多対多モデルと1対1モデルの両方を実装します。これは、古いバージョンのIRIXHP-UX、およびSolarisに見られます。

も参照してください

メモ

  1. ^ すべてではありませんが、多くの場合、IBMは、SVC番号、パラメーター・レジスターなどを文書化しました。
  2. ^ CP-67およびVMのCPコンポーネントは、仮想マシンからCPへのハイパーバイザーCALL(HVC)としてDiagnose(DIAG)命令を使用します。

参考文献

  1. ^ IBM(1967年3月)。「SVCルーチンの作成」。IBM System / 360オペレーティング・システム・システム・プログラマーズ・ガイド (PDF)第3版。pp。32–36。C28-6550-2。
  2. ^ 「syscalls(2)-Linuxのマニュアルページ」
  3. ^ OpenBSD(2013年9月14日)。「システムコール名(kern / syscalls.c)」BSD相互参照
  4. ^ NetBSD(2013年10月17日)。「システムコール名(kern / syscalls.c)」BSD相互参照
  5. ^ 「FreeBSDsyscalls.c、syscall名とIDのリスト」
  6. ^ 作成者:Mateusz "j00ru" Jurczyk(2017年11月5日)。「WindowsWIN32K.SYSシステムコールテーブル(NT / 2000 / XP / 2003 / Vista / 2008/7/8/10)」 {{cite web}}|author=一般名があります(ヘルプ
  7. ^ 「Plan9sys.h、システムコール名とIDのリスト」
  8. ^ 「SYSENTER(OSDev wiki)」
  9. ^ 匿名(2002年12月19日)。「Linux2.5はvsyscalls、sysenterサポートを取得します」KernelTrap2008年1月1日取得
  10. ^ Manu Garg(2006)。「Linux2.6のシステムコールベースのシステムコールメカニズム」
  11. ^ 「解放:x86命令セットリファレンス」renejeschke.de 2015年7月4日取得
  12. ^ シルバーシャッツ、アブラハム(2018)。オペレーティングシステムの概念ピーターBガルビン; グレッグ・ガニア(第10版)。ニュージャージー州ホーボーケン:ワイリー。p。67. ISBN 9781119320913OCLC1004849022 _
  13. ^ Bach、Maurice J.(1986)、 The Design of the UNIX Operating System、Prentice Hall、pp。15–16。
  14. ^ エリオット、ジョン(2011)。「Bach1986からの引用を含むProgClubでのシステムコール実装の議論」
  15. ^ 「スレッド」
  16. ^ 「スレッドモデル」(PDF)

外部リンク