デバイスツリー コンパイラ(DTC)を使用して、デバイスツリー ソース(DTS)ファイルをコンパイルできます。ただし、オーバーレイ デバイスツリー(DT)をターゲットのメイン DT に適用する前に、デバイスツリー オーバーレイ(DTO)の動作をシミュレートして結果を検証する必要もあります。
DTC を使用してコンパイルする
dtc を使用して .dts をコンパイルする場合、コンパイル結果の .dtbo に __symbols__ ノードを追加するためにオプション -@ を追加する必要があります。__symbols__ ノードには、すべてのノードのリストが含まれています。各ノードには、DTO ライブラリが参照に使用できるラベルが付けられています。
メイン DT の .dts をビルドするコマンドの例:
dtc -@ -O dtb -o my_main_dt.dtb my_main_dt.dts
オーバーレイ DT の .dts をビルドするコマンドの例:
dtc -@ -O dtb -o my_overlay_dt.dtbo my_overlay_dt.dts
ホストで DTO の結果を検証する
検証は、メイン DT にオーバーレイ DT を適用する際に発生する可能性があるエラーを特定するのに役立ちます。ターゲットを更新する前に、.dts で /include/ を使用して DTO の動作をシミュレートすると、ホストで DT をオーバーレイした場合の結果を検証できます。
図 1. 構文 /include/ を使用してホストで DTO をシミュレートする
- オーバーレイ .dtsのコピーを作成します。コピーの 1 行目のヘッダーを削除します。例:/dts-v1/; /plugin/; my_overlay_dt_wo_header.dtsという名前(または任意のファイル名)を付けて保存します。
- メインの .dtsのコピーを作成します。コピーの最後の行の後に、ステップ 1 で作成したファイルの include 構文を追加します。次に例を示します。/include/ "my_overlay_dt_wo_header.dts" my_main_dt_with_include.dtsという名前(または任意のファイル名)を付けて保存します。
- dtcを使用して- my_main_dt_with_include.dtsをコンパイルし、マージされた DT を取得します。この DT は DTO と同じ結果になるはずです。次に例を示します。- dtc -@ -O dtb -o my_merged_dt.dtb my_main_dt_with_include.dts 
- dtcを使用して- my_merged_dt.dtoをダンプします。- dtc -O dts -o my_merged_dt.dts my_merged_dt.dtb 
Android 9 で DTO を検証する
Android 9 では、デバイスツリー blob オーバーレイ(DTBO)パーティションが必要です。ノードを追加するか、または SoC DT のプロパティを変更するには、ブートローダーが SoC DT にデバイス固有の DT を動的にオーバーレイする必要があります。
適用されたオーバーレイを明示する
ベンダー テストスイート(VTS)がオーバーレイ アプリの正確性を評価できるようにするには、DTBO パーティションから選択されたオーバーレイを明示する新しいカーネル コマンドライン パラメータ androidboot.dtbo_idx をベンダーが追加する必要があります。カーネル バージョン 5.10 以降を使用している Android 12 では、このパラメータは bootconfig を通過します。たとえば、パラメータ androidboot.dtbo_idx=x,y,z は、x、y、z を、ブートローダーによって(この順序で)ベース DT に適用された DTBO パーティションからの DTO のゼロベースのインデックスとして報告します。
オーバーレイは、メイン DT からのノードに適用したり、新しいノードを追加したりできますが、以前のオーバーレイで追加されたノードを参照することはできません。オーバーレイ アプリによりオーバーレイのシンボル テーブルがメイン DT のシンボル テーブルとマージされることはないため、この制限は重要です(マージしないことにより、シンボル名の競合とオーバーレイ間の依存関係の複雑化を避けることができます)。
例: 無効なオーバーレイ
この例では、overlay_2.dts は overlay_1.dts によって追加されたノード e を参照しています。overlay_1 がメイン DT に適用された後、結果の DT に overlay_2 を適用しようとすると、ベース DT のシンボル テーブルにシンボル e が存在しないというエラーでオーバーレイ アプリが失敗します。
| main.dts | overlay_1.dts | overlay_2.dts | 
|---|---|---|
| 
[main.dts]
/dts-v1/;
/ {
  a: a {};
  b: b {};
  c: c {};
};
 | 
[overlay_1.dts]
/dts-v1/;
/plugin/;
&b { ref1 =  <&a>;
    e: e {
        prop = <0x0a>;
        phandle = <0x04>;
    };
};
 | 
[overlay_2.dts]
/dts-v1/;
/plugin/;
/* invalid! */
&e {
    prop = <0x0b>;
};
 | 
例: 有効なオーバーレイ
この例では、overlay_2.dts はメイン DTS からのノード b のみを参照しています。overlay_1 がベース DT に適用され、次に overlay_2 が適用されると、ノード e(overlay_1.dts によって設定される)にあるプロパティ prop の値が、overlay_2.dts によって設定された値で上書きされます。
| main.dts | overlay_1.dts | overlay_2.dts | 
|---|---|---|
| 
[final.dts]
/dts-v1/;
/ {
  a: a {};
  b: b {};
  c: c {};
};
 | 
[overlay_1.dts]
/dts-v1/;
/plugin/;
&b { ref1 =  <&a>;
     e {
          prop = <0x0c>;
      };
};
 | 
[overlay_2.dts]
/dts-v1/;
/plugin/;
/* valid */
&b { ref1 =  <&c>;
     e {
          prop = <0x0d>;
      };
};
 | 
DTBO パーティションを実装する
必要な DTBO パーティションを実装するため、ブートローダーが以下を行えることを確認します。
- ブートローダーが実行されているボードを特定し、それに応じて適用するオーバーレイを選択する。
- カーネル コマンドラインの末尾に androidboot.dtbo_idxパラメータを追加する。- パラメータは、ブートローダーがベース DT に適用した DTBO パーティション イメージからの DTO のゼロベースのインデックスを(同じ順序で)示す必要があります。
- インデックスは、DTBO パーティション内のオーバーレイの位置を参照する必要があります。
 
DTBO パーティションの構造の詳細については、デバイスツリー オーバーレイを参照してください。
DTBO パーティションを検証する
VTS を使用して、次のことが検証できます。
- カーネル コマンドライン パラメータ androidboot.dtbo_idxが存在すること(これを検証するには、Initが、対応するro.boot.dtbo_idxシステム プロパティを自動的に設定したかを確認します)。
- ro.boot.dtbo_idxシステム プロパティの有効性(これを検証するには、プロパティが少なくとも 1 つの有効な DTBO イメージ インデックスを指定しているかを確認します)。
- DTBO パーティションの有効性(ベース DT に適用された DTBO パーティションのオーバーレイも検証します)。
- オーバーレイ結果の DT の追加ノードまたはプロパティの変更が Linux カーネルに提示されること。
たとえば、次のオーバーレイと最終 DT では、カーネル コマンドラインへの androidboot.dtbo_idx=5,3 の追加は検証をパスしますが、カーネル コマンドラインへの androidboot.dtbo_idx=3,5 の追加は検証をパスしません。
| インデックス 3 のオーバーレイ DT | インデックス 5 のオーバーレイ DT | 
|---|---|
| 
[overlay_1.dts]
/dts-v1/;
/plugin/;
&c { prop = <0xfe>; };
 | 
[overlay_2.dts]
/dts-v1/;
/plugin/;
&c { prop = <0xff>; };
 | 
| 最終 DT | 
|---|
| 
/dts-v1/;
/ {
	a {
		phandle = <0x1>;
	};
	b {
		phandle = <0x2>;
	};
	c {
		phandle = <0x3>;
		prop = <0xfe>;
	};
	__symbols__ {
		a = "/a";
		b = "/b";
		c = "/c";
	};
};
   |