
この質問は、組み込みplatform device
ドライバーが起動時にどのように初期化されるかを理解しようとしたことから生まれました。
私は SoC (ARM + FPGA) 上で組み込み Linux ディストリビューション (Yocto) を使用しています。デバイス ドライバーは 用に作成されておりplatform device
、IP はデバイス ツリーでプラットフォーム デバイスとして記述されています。「互換性」プロパティは C ドライバーと一致しており、これまでのところすべて正常です。
プラットフォームデバイスのカーネルドキュメントを引用[1]、
一般的に、「互換性」プロパティを持つノードは何らかのデバイスを表すと想定され、次に、ツリーのルートにあるノードはプロセッサ バスに直接接続されているか、他の方法では説明できないさまざまなシステム デバイスであると想定できます。これらの各ノードに対して、Linux は platform_device を割り当てて登録し、それが platform_driver にバインドされることがあります。
だけでなく、
2.4 デバイス数
ボードが識別され、初期構成データが解析された後、カーネルの初期化を通常の方法で進めることができます。[...] また、このとき、ARM の machine_desc .init_early()、.init_irq()、および .init_machine() フックなどのマシン固有のセットアップ フックが呼び出されます。
[...]
DTコンテキストで最も興味深いフックは.init_machine()であり、これは主にLinuxデバイスモデルにプラットフォームに関するデータを入力する役割を担っています。
そして最終的には(Tegraボードのドキュメントの例に従って)
.init_machine() 時に、Tegra ボードのサポートコードはこの DT を見て、どのノードに platform_devices を作成するかを決定する必要があります。
そして、確かに調べてみるとarch/arm
[2init_machine
]デバイスツリーを「見る」関数は見つかりました。しかし、この関数はarm64アーキテクチャには存在しません。machine_desc
構造体腕のアーチにのみ存在する。
ソースコードを閲覧すると、デバイスツリー上のいくつかの操作を見つけることができましたが、どれも理解しにくいもので、setup_machine_fdt [4] が呼び出されearly_dt_scan
ますが、デバイスに入力されていないようです:
/* Retrieve various information from the /chosen node */
rc = of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
/* Initialize {size,address}-cells info */
of_scan_flat_dt(early_init_dt_scan_root, NULL);
/* Setup memory, calling early_init_dt_add_memory_arch */
of_scan_flat_dt(early_init_dt_scan_memory, NULL);
ここで問題となるのは、ブート プロセスを続行すると、 に到達し、 がdo_basic_setup
順番に を呼び出しdriver init
、最終的に が呼び出さbus_init
れることです。platform_bus_init
of_core_init
最後のものは「devicetree」という kset を作成するので、少し期待していました。ただし、ここでツリーが実際に解析されるかどうかはわかりません。
この後、 がinitcalls
呼び出され、ドライバーの初期化が行われることになりますが、ここでは DT 解析はどこで行われたのでしょうか? 「compatible」プロパティは実際にどこで使用されたのでしょうか? 再びドキュメントから引用します:
カーネルはツリーのルートから始めて、「互換性のある」プロパティを持つノードを探すというトリックがあります。まず、「互換性のある」プロパティを持つノードは何らかのデバイスを表すと一般に想定され、次に、ツリーのルートにあるノードはプロセッサ バスに直接接続されているか、他の方法では説明できないさまざまなシステム デバイスであると想定されます。これらの各ノードについて、Linux は platform_device を割り当てて登録し、それが platform_drive にバインドされることがあります。
「プラットフォーム ドライブにバインド」の部分は、ドライバー コードによって定義された initcall によって実行されますが、「プラットフォーム デバイスを割り当てて登録する」という部分が理解できません。