Linux ユーザー空間では、システム コールを呼び出す必要があることがよくあります。 Linux バージョン 2.6.37 を例として、読み取りシステム コールの実装を追跡してみましょう。システム コールの実装は、Linux のバージョンによって異なる場合があります。
一部のアプリケーションでは、次の定義が見られます:
リーリー実際に呼び出されるのは、システム関数 syscall(SYS_read)、つまり sys_read() 関数です。 Linux バージョン 2.6.37 では、この機能はいくつかのマクロ定義によって実装されます。
Linux システム コール (SCI、システム コール インターフェイス) は、実際にはマルチチャネルの集約と分解のプロセスであり、集約ポイントは 0x80 割り込みエントリ ポイント (X86 システム構造) です。つまり、すべてのシステム コールはユーザー空間から 0x80 割り込みポイントまで集約され、同時に特定のシステム コール番号が保存されます。 0x80 割り込みハンドラが実行されている場合、システム コール番号に応じて異なるシステム コールが個別に処理されます。つまり、異なるカーネル関数が呼び出されて処理されます。
システムコールを発生させるには 2 つの方法があります:
(1) int $0×80、これは古い Linux カーネル バージョンでシステム コールを引き起こす唯一の方法です。
(2) sysenter の組み立て説明書
Linux カーネルでは、次のマクロ定義を使用してシステム コールを実行できます。
リーリーSYSCALL_DEFINE3 のマクロ定義は次のとおりです。
リーリー## はマクロ内の文字が直接置換されることを意味します。
name = read の場合、マクロ内では __NR_##name が __NR_read に置き換えられます。 #NR##name はシステム コール番号、## は 2 つのマクロ展開を指します。つまり、「name」を実際のシステム コール名に置き換えて、__NR.... を展開します。 name == ioctl の場合、__NR_ioctl です。
リーリー
__SYSCALL_DEFINEx(x, sname, VA_ARGS) リーリー
次のタイプのマクロ定義が最終的に呼び出されます:
asmlinkage の長いシステム##name(__SC_DECL##x(VA_ARGS))
それが、前に説明した sys_read() システム関数です。
asmlinkage は、スタックから関数の引数のみを抽出するようにコンパイラーに指示します。すべてのシステムコールにはこの修飾子が必要です。これは、以前の記事 quagga で説明したマクロ定義に似ています。
リーリー
コード分析:
file_pos_write() を呼び出して、ファイルの現在の読み取りおよび書き込み位置を更新します。
以上がSyscall システムコール Linux カーネルトレースの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。