Linux のソースツリーは、アーキテクチャ非依存のサブシステム、アーキテクチャポート、公開ユーザー空間インターフェイス、生成されたビルド状態、ツール、テストを分離します。ディレクトリ名はナビゲーションの手がかりであり、実行モデルではありません。Kconfig が設定を選択し、Kbuild がオブジェクトを選択し、選択されたオブジェクトが特定のカーネルイメージに到達するものを決定します。
トップレベルのサブシステム境界 #
主なソースディレクトリは次のとおりです。
| パス | 役割 |
|---|---|
arch/ | アーキテクチャポート、ブートコード、MMU と割り込みのエントリ、低レベル ABI サポート。 |
block/, fs/, mm/, net/ | ブロック層、VFS とファイルシステム実装、仮想および物理メモリ管理、ネットワークスタック。 |
kernel/, init/, ipc/, security/ | コアスケジューリング、ロック、シグナル、トレース、その他のカーネル機能、初期化、IPC、Linux Security Module インフラストラクチャ。 |
drivers/, sound/, virt/ | デバイスドライバー、サウンドサブシステム、KVM などの仮想化サポート。ドライバーは struct file_operations を公開する必要はなく、サブシステム固有のバスとコールバックも一般的です。 |
crypto/, lib/, io_uring/, rust/ | 共有暗号およびライブラリサポート、非同期 I/O、Rust カーネルサポート。 |
include/, Documentation/, scripts/ | ヘッダー、保守されるドキュメント、Kbuild/Kconfig、および生成・保守ユーティリティ。 |
tools/, samples/, usr/ | perf などのユーザー空間ツール、サンプルプログラム、組み込み initramfs の生成。 |
certs/ や LICENSES/ などの他のトップレベル要素は、署名、ライセンス、またはビルドポリシーをサポートします。ソースチェックアウトは時間とともに変化するため、すべてのリリースに同じディレクトリが含まれると仮定せず、トップレベルの README、MAINTAINERS、Documentation/ を確認してください。
Kbuild の集約と最終リンク #
Kbuild は Makefile または Kbuild ファイルを読み取り、obj-$(CONFIG_FOO) エントリを評価します。y は組み込みオブジェクトを、m はロード可能なモジュールを選択し、未設定のシンボルはどちらも選択しません。ビルドが選択されたディレクトリを下っていくと、obj-y オブジェクトを薄い built-in.a アーカイブにまとめます。その後、アーカイブと選択された他のオブジェクトが vmlinux にリンクされ、モジュールは別のリンクパスに従います。
順序は重要です。Kbuild ドキュメントが、初期化順序を含むアーカイブと最終リンクの動作を定義しているためです。したがって、built-in.a があるというだけでディレクトリが自己完結した「モジュール」になるわけではありません。設定と親 Makefile が、そのディレクトリを訪問するかどうか、オブジェクトが最終イメージに到達するかどうかを制御します。
設定とビルドルールの両方を通じて機能を追跡します。
git grep -n 'CONFIG_FOO'
git grep -n 'obj-$(CONFIG_FOO)'シンボル検索だけで結論を出す前に、周囲の Kconfig と Makefile エントリを読みます。条件付きコンパイル、生成ヘッダー、アーキテクチャのオーバーライド、リンク順序によって別の実装が選択される可能性があるためです。
ヘッダーファミリーとユーザー空間 ABI #
カーネル非公開、ユーザー空間に公開、アーキテクチャ固有、生成されたヘッダーは分離されています。
| パス | 目的 |
|---|---|
include/ | アーキテクチャ非依存のカーネル内部ヘッダー。 |
include/uapi/ | アーキテクチャ非依存のユーザー空間 ABI ヘッダー。 |
arch/<arch>/include/ | アーキテクチャ固有のカーネル内部ヘッダー。 |
arch/<arch>/include/uapi/ | アーキテクチャ固有のユーザー空間 ABI ヘッダー。 |
include/generated/ and arch/<arch>/include/generated/ | ビルドで生成されたヘッダー。 |
make headers_install はサニタイズされた UAPI ヘッダーセットをエクスポートします。アプリケーションはカーネルチェックアウト内の任意の内部ヘッダーではなく、オペレーティングシステムまたはツールチェーンが提供するインストール済みヘッダーを使用すべきです。task_struct などの構造体は安定したユーザー空間インターフェイスではありません。ヘッダーインストールのドキュメントがサポートされるエクスポート操作を定義します。
生成状態と出力ツリー #
設定は .config に書き込み、コンパイル前に生成ヘッダーを作成します。Kbuild は生成ファイルとオブジェクトを別の出力ディレクトリに配置できます。
make O="$PWD/out" defconfig
make O="$PWD/out" -j"$(nproc)"アウトオブツリーのビルドは生成状態をチェックアウトから分離しますが、ソースツリーと出力ツリーは設定、生成ヘッダー、依存関係メタデータを通じて結合されたままです。出力ディレクトリを移動または部分的にコピーした場合は、増分ビルドの古い依存関係状態に頼らず再設定します。
コードの検索とインデックスの準備 #
MAINTAINERS はサブシステムの所有権と、推奨されるパッチ経路の情報を記録します。ツリーを中央で所有される 1 つのプログラムとして扱うのではなく、影響を受けるサブシステムのプロセスとドキュメントに従います。メンテナーハンドブックにサブシステム固有のガイダンスがまとめられています。
宣言とサブシステムのドキュメントから実装の調査を始め、その後で定義を検索します。
git grep -n 'SYSCALL_DEFINE.*openat'
git grep -n 'struct file_operations'tools/、生成出力、ビルド成果物がカーネル空間の結果を隠す可能性があるため、エディターのインデックスには意図的な除外が有効です。たとえば次のようにします。
{
"C_Cpp.default.includePath": ["${workspaceFolder}/include"],
"search.exclude": {
"**/tools/**": true,
"**/include/generated/**": true,
"**/out/**": true
}
}ユーザー空間ツールまたは生成されたインターフェイスを調査する場合は、パスを盲目的に除外しないでください。除外はインデックス作成上の選択であり、Kconfig と Kbuild の経路はカーネルビルドに含まれるものの証拠として残ります。
コメント
GitHub で閲覧・コメントする(投稿にはログインが必要です)