コンパイルと確認

デバイスツリー コンパイラ(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 をシミュレートする

  1. オーバーレイ .dts のコピーを作成します。コピーの 1 行目のヘッダーを削除します。例:
    /dts-v1/;
    /plugin/;
    
    ファイルに my_overlay_dt_wo_header.dts という名前(または任意のファイル名)を付けて保存します。
  2. メインの .dts のコピーを作成します。コピーの最後の行の後に、ステップ 1 で作成したファイルの include 構文を追加します。次に例を示します。
    /include/ "my_overlay_dt_wo_header.dts"
    
    ファイルに my_main_dt_with_include.dts という名前(または任意のファイル名)を付けて保存します。
  3. dtc を使用して my_main_dt_with_include.dts をコンパイルし、マージされた DT を取得します。この DT は DTO と同じ結果になるはずです。次に例を示します。
    dtc -@ -O dtb -o my_merged_dt.dtb my_main_dt_with_include.dts
    
  4. 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 は、xyz を、ブートローダーによって(この順序で)ベース DT に適用された DTBO パーティションからの DTO のゼロベースのインデックスとして報告します。

オーバーレイは、メイン DT からのノードに適用したり、新しいノードを追加したりできますが、以前のオーバーレイで追加されたノードを参照することはできません。オーバーレイ アプリによりオーバーレイのシンボル テーブルがメイン DT のシンボル テーブルとマージされることはないため、この制限は重要です(マージしないことにより、シンボル名の競合とオーバーレイ間の依存関係の複雑化を避けることができます)。

例: 無効なオーバーレイ

この例では、overlay_2.dtsoverlay_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 が適用されると、ノード eoverlay_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 パーティションを実装するため、ブートローダーが以下を行えることを確認します。

  1. ブートローダーが実行されているボードを特定し、それに応じて適用するオーバーレイを選択する。
  2. カーネル コマンドラインの末尾に 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";
	};
};