
Linuxカーネルは、ユーザー空間コードとカーネルモードコードへの複数のインターフェースを提供します。これらのインターフェースは、アプリケーションプログラミングインターフェース(API)またはアプリケーションバイナリインターフェース(ABI)に分類でき、さらにカーネルユーザー空間インターフェースとカーネル内部インターフェースに分類できます。


Linux API にはカーネル-ユーザー空間 API が含まれており、これによりユーザー空間のコードから Linux カーネルのシステム リソースやサービスにアクセスできるようになります。[ 3 ]これは、Linux カーネルのシステム コール インターフェイスとC 標準ライブラリのサブルーチンで構成されています。Linux API の開発の焦点は、POSIXで定義されている仕様の使用可能な機能を、合理的に互換性があり、堅牢で、高性能な方法で提供すること、および POSIX で定義されていない追加の有用な機能を提供することにあります。これは、POSIX API を実装する他のシステムのカーネル-ユーザー空間 API が、POSIX で定義されていない追加の機能を提供しているのと同様です。
Linux API は、破壊的変更を導入しないという方針により、何十年にもわたって意図的に安定性を維持してきました。この安定性により、ソースコードの移植性が保証されます。[ 4 ]同時に、Linux カーネル開発者は、新しいシステムコールを導入することに関して、歴史的に保守的かつ綿密でした。
利用可能なフリーソフトウェアやオープンソースソフトウェアの多くは、POSIX API 用に記述されています。他の POSIX 準拠のカーネルと C 標準ライブラリの組み合わせと比較して、Linux カーネルにははるかに多くの開発が投入されているため、Linux カーネルとその API には追加機能が追加されています。POSIX API だけでなく、完全な Linux API 用にプログラミングすることで、追加機能が役立つ場合にメリットが得られる可能性があります。現在のよく知られた例としては、udev、systemd、Westonなどがあります。[ 5 ] Lennart Poetteringのような人々は、メリットがある場合は POSIX API よりも Linux API を優先することを公然と提唱しています。[ 6 ]
FOSDEM 2016で、 Michael KerriskはLinuxカーネルのユーザー空間APIに関するいくつかの問題点について説明し、拡張性がなく、保守性がなく、過度に複雑で、目的が限定的で、標準に違反し、一貫性がないなど、複数の設計上のエラーが含まれていると述べた。これらのエラーのほとんどは、修正するとカーネルがユーザー空間に提示するABIが壊れてしまうため、修正できない。[ 7 ]
カーネルのシステムコールインターフェースとは、カーネル内で実装され利用可能なすべてのシステムコールの集合です。Linuxカーネルでは、ダイレクトレンダリングマネージャ(DRM)などのさまざまなサブシステムが独自のシステムコールを定義しており、それらはすべてシステムコールインターフェースの一部となっています。
Linuxカーネルのシステムコールの構成に関するさまざまな問題が公に議論されている。問題はAndy Lutomirski、 Michael Kerriskらによって指摘されている。 [ 8 ] [ 9 ] [ 10 ] [ 11 ]

Linux 用のC標準ライブラリには、Linux カーネルのシステムコールをラップする関数が含まれています。Linux カーネルのシステムコールインターフェースと C 標準ライブラリの組み合わせが、Linux API を構築します。C 標準ライブラリの一般的な実装には、次のようなものがあります。
状況は変化しつつあるものの、これらの選択肢の中でglibcは依然として最も人気のある実装であり、多くの人がglibcをデフォルトとして扱い、libcと同義語として用いるほどである。
他のUnix系システムと同様に、LinuxカーネルにはPOSIXに含まれていない追加機能が存在する。
futex(高速ユーザースペースミューテックス)epoll、、、、、spliceおよびは、dnotifyこれまでLinuxカーネル専用でした。fanotifyinotifygetrandomのメインラインバージョン3.17で導入されました[ 12 ]memfdkdbus開発者によって提案されました[ 13 ]memfd_createLinuxカーネルのメインラインにカーネルバージョン3.17でマージされました。readaheadページキャッシュへのファイルの「先読み」を開始しますDRMは、明確に定義され、高性能なフリーおよびオープンソースのグラフィックスデバイスドライバの開発と実装において極めて重要な役割を果たしており、これなしではレンダリングアクセラレーションは全く利用できず、 X.Orgサーバーでは2Dドライバしか利用できないだろう。DRMはLinux向けに開発され、その後他のオペレーティングシステムにも移植された。[ 14 ]

Linux ABIはカーネルとユーザー空間間のABIです。ABIはマシンコードインターフェースであるため、Linux ABIは命令セットに縛られています。有用なABIを定義し、それを安定的に維持することは、Linuxカーネル開発者やGNU Cライブラリ開発者の責任というよりも、複数のLinux ABIをサポートするのではなく、単一のLinux ABI専用のバイナリとして独自のソフトウェアを販売およびサポートしたいと考えているLinuxディストリビューションや独立系ソフトウェアベンダー(ISV)の責任と言えるでしょう。
ABIは、 x86、x86-64、MIPS、ARMv7-A(32ビット)、ARMv8-A(64ビット)などの各命令セットに対して、エンディアンとともに定義する必要があります(両方がサポートされている場合)。
ABIで指定された定義に対して、異なるコンパイラを使用してソフトウェアをコンパイルし、完全なバイナリ互換性を実現できる必要があります。フリーでオープンソースのコンパイラとしては、 GNU Compiler Collection、LLVM / Clangなどがあります。
カーネル内部には、カーネルサブシステム間のインターフェースを可能にする多くのAPIが存在します。これらは比較的安定して維持されていますが、安定性が保証されているわけではありません。新たな研究や知見によって必要性が示された場合、カーネル内部APIは変更される可能性があります。必要な変更とテストはすべて開発者自身が行う必要があります。
Linuxカーネルはモノリシックカーネルであるため、デバイスドライバはカーネルコンポーネントです。メインカーネルツリーの外で(独自の)デバイスドライバを保守する企業の負担を軽減するために、デバイスドライバ用の安定したAPIが繰り返し要求されてきました。Linuxカーネル開発者は、デバイスドライバ用の安定したカーネル内APIを保証することを繰り返し拒否してきました。そのような保証は、過去にLinuxカーネルの開発を阻害し、将来も阻害する可能性があり、また、フリーソフトウェアおよびオープンソースソフトウェアの性質上、必要ありません。したがって、Linuxカーネルは意図的に安定したカーネル内APIを持っていません。[ 15 ]
安定したカーネル内APIが存在しないため、安定したカーネル内ABIも存在し得ない。[ 16 ]


多くのユースケースにおいて、Linux APIは低レベルすぎると考えられているため、より抽象度の高いAPIを使用する必要があります。高レベルのAPIは、低レベルのAPIの上に実装する必要があります。例:
変更によってユーザー プログラムが動作しなくなった場合、それはカーネルのバグです。ユーザー プログラムのせいにすることは決してありません。
実際、私の見解では、
Linux API は
POSIX API の役割を担っており、Linux はすべてのフリー ソフトウェア開発の中心となっています。そのため、開発者には Linux だけを念頭に置いてハッキングを試みて、Linux が提供する自由と機会を体験することをお勧めします。ですから、
The Linux Programming Interfaceのコピーを入手し、
POSIX
互換性について書かれていることはすべて無視して
、素晴らしい Linux ソフトウェアをハッキングしてください。とても楽になりますよ!
{{cite web}}: CS1メンテナンス: アーカイブサービスは非推奨になりました (リンク)