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


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

Linux用のC標準ライブラリには、Linuxカーネルのシステムコールのラッパーが含まれています。LinuxカーネルのシステムコールインターフェースとC標準ライブラリの組み合わせがLinux APIを構成します。C標準ライブラリの一般的な実装には、以下のものがあります。
状況は変化していますが、これらのオプションの中では、glibc が依然として最も人気のある実装であり、多くの人がこれをデフォルトとして扱い、libc と同等の用語として扱っています。
他のUnix 系システムと同様に、Linux カーネルには POSIX に含まれない追加機能が存在します。
futex(高速ユーザー空間ミューテックス) epoll、、、、spliceはdnotify、これまで Linux カーネル専用でしたfanotify。inotifygetrandomのバージョン3.17で導入されました[12]memfdkdbus開発者によって提案された[13]
memfd_createカーネルバージョン3.17でLinuxカーネルメインラインに統合されました。readaheadページキャッシュへのファイルの「先読み」を開始しますDRMは、明確に定義され、高性能なフリーでオープンソースのグラフィックデバイスドライバの開発と実装に不可欠でした。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だけを念頭に置いてハッキングを試し、それがもたらす自由と機会を体験することをお勧めします。ですから、『
The Linux Programming Interface』を手に入れて、
POSIX
互換性に関する記述はすべて無視し
、素晴らしいLinuxソフトウェアをハッキングしてみてください。きっと気分が良くなるはずです!