web-dev-qa-db-ja.com

システムコールは、ユーザーランドからLinuxカーネルと対話する唯一の方法ですか?

他のインターフェースはありますか?/procファイルシステム?

3
jl6

LinuxカーネルのsyscallAPIはプライマリAPIであり(libcの下に隠されており、プログラマーが直接使用することはめったにありません)、ほとんどの標準IPCメカニズムはすべてがファイルアプローチであり、最終的に読み取り/書き込み(およびそれ以上)の呼び出しが必要になるため、ここではそれらを排除します。

ただし、ほとんどのプラットフォームでは(そこに到達するためにすべてのシステムコールを除外した場合)、次の方法があります: [〜#〜] vdso [〜#〜] 。これは、カーネルが1つ(または複数)のわずかに魔法のページを各プロセスにマップするメカニズムです(通常はELF .soの形式で)。これは、_linux-vdso.so_またはlddまたは_/proc/PID/maps_と同様に表示されます。これは、カーネルとユーザープロセスの間で効果的にメモリマップされますIPC(現在の実装では一方向ですが)。

これは一般にシステムコールを高速化するために使用され、元々はx86のパフォーマンスの問題に対処するために実装されました( _linux-gate.so_ )が、カーネルデータやアクセス関数も含まれる場合があります。 getcpu()gettimeofday()のような呼び出しは、actualsyscallとカーネルコンテキストスイッチを作成するのではなく、これらを使用する場合があります。これらの最適化された呼び出しの可用性は、glibcスタートアップコードによって検出および有効化されます(プラットフォームの可用性によって異なります)。現在の実装には、直接読み取ることができる「VVAR」ページと呼ばれる共有カーネル変数の(読み取り専用)ページが含まれています。

_strace -e trace=clock_gettime date_の出力を調べて、dateコマンドがclock_gettime()システムコールを実行するかどうかを確認することでこれを確認できますが、VDSOが機能している場合は実行されません(時刻はVDSOページの関数によるVVARSページ。 _Arch/x86/vdso/vclock_gettime.c_ を参照してください。

ここに役立つ技術的な要約があります: http://blog.tinola.com/?e=5 より詳細なチュートリアル: http://www.linuxjournal.com/content/creating -vdso-colonels-other-chicken 、およびマニュアルページ: http://man7.org/linux/man-pages/man7/vdso.7.html

9
mr.spuratic

番号。

些細な反例、これはカーネルと相互作用します:

int main() {
    volatile char *silly = 0;
    *silly = 'a';
}

これにより、カーネルのページフォールトハンドラーが呼び出され、最終的にプロセスがSIGSEGVを取得します(Cによる未定義の動作であるため、コンパイラーがそのコードを「最適化」して明白な以外のことを実行しないと想定します)標準では、必ず-O0)でコンパイルしてください。

8
derobert