Linuxカーネル学習ノート(5)-システム呼び出し
4967 ワード
1、カーネルとの通信
システム呼び出しは、ユーザ空間プロセスとハードウェアデバイスとの間に中間層を追加する.機能:は、ユーザ空間にハードウェアの抽象インタフェースを提供する. システム呼び出しは、システムの安定性と安全性を保証する. システム呼び出し時にユーザ空間がカーネルにアクセスする唯一の手段(異常と陥没を除く).
2、API、POSIX及びCライブラリ
アプリケーションは、システム呼び出しによって直接プログラミングされるのではなく、ユーザ空間によって実装されるアプリケーションプログラミングインターフェース(API)によってプログラミングされる.Unixで最もポピュラーなアプリケーションプログラミングインターフェースはPOSIX規格に基づいており、POSIXで定義されたAPI関数とシステム呼び出しの間には直接関係がある.標準Cライブラリ関数とシステム呼び出しインタフェースを含むUnixシステムの主要なAPIを実現した.
3、システム呼び出し
getpid()システム呼び出しの実装:
SYSCALL_DEFINE 0は、パラメータなし(0)のシステム呼び出しを定義するマクロで、展開後は次のようになります.
asmlinkageはコンパイル命令であり、コンパイラがスタックから関数のパラメータのみを抽出することを通知します.すべてのシステム呼び出しはこの限定語を使用します.sys_name()はLinuxシステム呼び出しの命名規則です.
3.1システム呼び出し番号
Linuxでは、各システム呼び出しにシステム呼び出し番号が与えられる.システム呼び出し番号の割り当て後は変更できません.システム呼び出しが削除された場合、使用するシステム呼び出し番号は再利用できません. sys_ni_Syscall()は、システム呼び出しが実現されていないことを示し、ENOSYSのみを返し、無効なシステム呼び出しのために設定します.システム呼び出しのリストはsys_に格納されます.call_テーブルにあります.
3.2システム呼び出しの性能
Linuxシステム呼び出しは、他のオペレーティングシステムよりも高速です.Linuxコンテキストの切り替え時間が短いため、システム呼び出しハンドラと各システム呼び出し自体は非常に簡潔です.
4、システムコールハンドラ
ユーザ空間のプログラムは、保護されたアドレス空間にカーネルが存在するため、カーネルコードを直接実行することができず、カーネル空間の関数を直接呼び出すことができません. アプリケーションは、ソフト割り込みによりカーネル実行システム呼び出しを通知し、システムをカーネル状態に切り替えて異常処理プログラム(システム呼び出し処理プログラム)を実行する異常を発生させる. X 86システムが予め定義したソフト割り込みは割り込み番号128であり、
4.1適切なシステム呼び出しの指定
x 86システムでは、システム呼び出し番号がeaxレジスタを介してカーネルに渡される.
システム呼び出しテーブルのテーブル項目は64ビット(8バイト)タイプで格納され、x 86-32システムでは8の代わりに4が使用される.
4.2パラメータ伝達
x 86-32システムでは、ebx、ecx、edx、esi、ediの順に最初の5つのパラメータが格納されます.ユーザ空間に与えられた戻り値はeaxレジスタに格納される.
5、システム呼び出しの実現
5.1システム呼び出しの実現
システム呼び出しのインタフェースは簡潔で、パラメータはできるだけ少なく、できるだけ将来のために多く考慮しなければならない. フラグは、単一のシステム呼び出しに複数の異なる動作を持たせるために使用されるのではなく、新しい機能とオプションを追加しても、後方互換性を破壊したり、不要な新しいシステム呼び出しを追加したりするために使用される.
5.2パラメータ検証
システム呼び出しは、すべてのパラメータが合法的に有効であるかどうかをよく確認する必要があります.たとえば、ユーザ空間のポインタを受信する前に、カーネルは次のことを保証する必要があります.ポインタが指すメモリ領域はユーザ空間に属する. ポインタが指すメモリ領域は、プロセスのアドレス空間にある. 読み取りの場合、メモリは読み取り可能としてマークされるべきである.書き込みの場合は、メモリに書き込み可能とマークする必要があります.実行可能の場合、メモリは実行可能とマークされます.
ユーザ空間にデータを書き込むには、カーネルが
6、システム呼び出しコンテキスト
カーネルは、システム呼び出しを実行するときにプロセスコンテキストにあります.Currentポインタは、システム呼び出しを開始するプロセスを指します.プロセスコンテキストでは、カーネルはスリープされ、プリエンプトされます.スリープ可能な説明システム呼び出しは、カーネルが提供するほとんどの機能を使用することができる.現在のプロセスは他のプロセスによって優先され、同じシステム呼び出しを使用する場合、システム呼び出し時に再入力できることを保証します.
6.1バインドシステム呼び出し
正式なシステム呼び出しの登録:-システム呼び出しテーブルの最後にテーブル項目を追加します.システム呼び出し番号は0から計算されます.-サポートされているさまざまなアーキテクチャでは、システム呼び出し番号は
6.2ユーザ空間アクセスシステムから呼び出す
Linuxは、
第1のパラメータはシステム呼び出しの戻り値タイプであり、第2のパラメータはシステム呼び出しの名前であり、その後はシステム呼び出しの各パラメータのタイプと名前である.
6.3システム呼び出しのメリットとデメリット
は通常、システム呼び出しによって実現されない.メリット:システム呼び出しの作成が容易で、使いやすい. Linuxシステム呼び出しの高性能は明らかです.
質問:にはシステム呼び出し番号が必要です.カーネルが開発バージョンにあるときに公式に割り当てられる必要があります. システム呼び出しは安定カーネルに加えられて硬化し、インタフェースの変更は許されない. は、システム呼び出しをサポートする必要がある各アーキテクチャにそれぞれ登録する必要がある. スクリプトではシステム呼び出しが容易ではなく、ファイルシステムからシステム呼び出しに直接アクセスすることもできません. システム呼び出し番号が必要なため、メインカーネルツリー以外ではシステム呼び出しのメンテナンスと使用が困難です. 単純な情報交換のみを行うと、システム呼び出しは役に立たない.
代替方法:信号量のようなインタフェースは、ファイル記述子で表すことができ、read()などの方法で操作することができる. 増加した情報をsysfsの適切な位置にファイルとして置く.
システム呼び出しは、ユーザ空間プロセスとハードウェアデバイスとの間に中間層を追加する.機能:
2、API、POSIX及びCライブラリ
アプリケーションは、システム呼び出しによって直接プログラミングされるのではなく、ユーザ空間によって実装されるアプリケーションプログラミングインターフェース(API)によってプログラミングされる.Unixで最もポピュラーなアプリケーションプログラミングインターフェースはPOSIX規格に基づいており、POSIXで定義されたAPI関数とシステム呼び出しの間には直接関係がある.標準Cライブラリ関数とシステム呼び出しインタフェースを含むUnixシステムの主要なAPIを実現した.
3、システム呼び出し
getpid()システム呼び出しの実装:
SYSCALL_DEFINE0(getpid)
{
return task_tgid_vnr(current);
}
SYSCALL_DEFINE 0は、パラメータなし(0)のシステム呼び出しを定義するマクロで、展開後は次のようになります.
asmlinkage long sys_getpid(void)
asmlinkageはコンパイル命令であり、コンパイラがスタックから関数のパラメータのみを抽出することを通知します.すべてのシステム呼び出しはこの限定語を使用します.sys_name()はLinuxシステム呼び出しの命名規則です.
3.1システム呼び出し番号
Linuxでは、各システム呼び出しにシステム呼び出し番号が与えられる.システム呼び出し番号の割り当て後は変更できません.システム呼び出しが削除された場合、使用するシステム呼び出し番号は再利用できません. sys_ni_Syscall()は、システム呼び出しが実現されていないことを示し、ENOSYSのみを返し、無効なシステム呼び出しのために設定します.システム呼び出しのリストはsys_に格納されます.call_テーブルにあります.
3.2システム呼び出しの性能
Linuxシステム呼び出しは、他のオペレーティングシステムよりも高速です.Linuxコンテキストの切り替え時間が短いため、システム呼び出しハンドラと各システム呼び出し自体は非常に簡潔です.
4、システムコールハンドラ
ユーザ空間のプログラムは、保護されたアドレス空間にカーネルが存在するため、カーネルコードを直接実行することができず、カーネル空間の関数を直接呼び出すことができません. アプリケーションは、ソフト割り込みによりカーネル実行システム呼び出しを通知し、システムをカーネル状態に切り替えて異常処理プログラム(システム呼び出し処理プログラム)を実行する異常を発生させる. X 86システムが予め定義したソフト割り込みは割り込み番号128であり、
int $0x80
命令によりトリガされ、異常処理プログラムsystem_を実行するcall().x 86プロセッサの新しい命令sysenter
は、より速く、より専門的にカーネルに陥ります.4.1適切なシステム呼び出しの指定
x 86システムでは、システム呼び出し番号がeaxレジスタを介してカーネルに渡される.
system_call()
は、システム呼び出し番号をNR_syscalls
と比較し、NR_syscalls
以上は-ENOSYS
を返します.システム呼び出しコードを実行します.call *sys_call_table(, %rax, 8);
システム呼び出しテーブルのテーブル項目は64ビット(8バイト)タイプで格納され、x 86-32システムでは8の代わりに4が使用される.
4.2パラメータ伝達
x 86-32システムでは、ebx、ecx、edx、esi、ediの順に最初の5つのパラメータが格納されます.ユーザ空間に与えられた戻り値はeaxレジスタに格納される.
5、システム呼び出しの実現
5.1システム呼び出しの実現
システム呼び出しのインタフェースは簡潔で、パラメータはできるだけ少なく、できるだけ将来のために多く考慮しなければならない. フラグは、単一のシステム呼び出しに複数の異なる動作を持たせるために使用されるのではなく、新しい機能とオプションを追加しても、後方互換性を破壊したり、不要な新しいシステム呼び出しを追加したりするために使用される.
5.2パラメータ検証
システム呼び出しは、すべてのパラメータが合法的に有効であるかどうかをよく確認する必要があります.たとえば、ユーザ空間のポインタを受信する前に、カーネルは次のことを保証する必要があります.
ユーザ空間にデータを書き込むには、カーネルが
copy_to_user()
の方法を提供します.最初のパラメータはプロセス空間の目的メモリアドレスであり、2番目はカーネル空間内のソースアドレスであり、最後のパラメータはコピーが必要なデータ長である.ユーザ空間からデータを読み出し、カーネルはcopy_from_user()
の方法を提供する.2番目のパラメータ指定位置のデータを1番目のパラメータ指定位置にコピーします. 実行に失敗し、関数はコピーが完了しなかったデータのバイト数を返します.正常に0を返しました.関数はブロックを引き起こす可能性があります.カーネルは、正当な権限があるかどうかを確認します.capable()
関数を使用して、指定したリソースを操作する権限があるかどうかを確認し、0以外の権限のある操作を返します.6、システム呼び出しコンテキスト
カーネルは、システム呼び出しを実行するときにプロセスコンテキストにあります.Currentポインタは、システム呼び出しを開始するプロセスを指します.プロセスコンテキストでは、カーネルはスリープされ、プリエンプトされます.スリープ可能な説明システム呼び出しは、カーネルが提供するほとんどの機能を使用することができる.現在のプロセスは他のプロセスによって優先され、同じシステム呼び出しを使用する場合、システム呼び出し時に再入力できることを保証します.
6.1バインドシステム呼び出し
正式なシステム呼び出しの登録:-システム呼び出しテーブルの最後にテーブル項目を追加します.システム呼び出し番号は0から計算されます.-サポートされているさまざまなアーキテクチャでは、システム呼び出し番号は
6.2ユーザ空間アクセスシステムから呼び出す
Linuxは、
_syscalln()
マクロを使用してシステム呼び出しを呼び出します.ここで、nの範囲は0から6で、システム呼び出しに渡す必要があるパラメータの数を表します.//open()
long open(const char *filename, int flags, int mode)
//
#define NR_open 5
_syscall113(long, open, const char*, filename, int, flags, int, mode)
第1のパラメータはシステム呼び出しの戻り値タイプであり、第2のパラメータはシステム呼び出しの名前であり、その後はシステム呼び出しの各パラメータのタイプと名前である.
6.3システム呼び出しのメリットとデメリット
は通常、システム呼び出しによって実現されない.メリット:
質問:
代替方法: