編譯和驗證

您可以使用裝置樹編譯器(DTC)來編譯裝置樹原始檔。然而,在目標主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 結果

驗證可以幫助您識別將覆蓋裝置識別碼放置在主裝置識別碼上時可能發生的錯誤。在更新目標之前,您可以透過使用.dts中的/include/模擬 DTO 的行為來驗證在主機上覆蓋 DT 的結果。

圖 1.使用語法/include/在主機上模擬 DTO
  1. 建立覆蓋.dts的副本。在副本中,刪除第一行標題。範例:
    /dts-v1/;
    /plugin/;
    
    將檔案另存為my_overlay_dt_wo_header.dts (或任何您想要的檔案名稱)。
  2. 建立主.dts的副本。在副本中的最後一行之後,附加您在步驟 1 中建立的檔案的包含語法。例如:
    /include/ "my_overlay_dt_wo_header.dts"
    
    將檔案另存為my_main_dt_with_include.dts (或您想要的任何檔案名稱)。
  3. 使用dtc編譯my_main_dt_with_include.dts得到合併後的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)能夠評估覆蓋應用程式的正確性,供應商必須添加新的核心命令列參數androidboot.dtbo_idx ,該參數指示從 DTBO 分區中選擇的覆蓋。在使用核心版本 5.10 或更高版本的 Android 12 中,此參數透過 bootconfig 傳遞。例如,參數androidboot.dtbo_idx=x,y,zxyz報告為設備樹覆蓋 (DTO) 的從零開始的索引,該索引來自引導程式(按順序)應用於基礎的 DTBO 分區設備樹(DT)。

覆蓋可以應用於主設備樹中的節點或新增節點,但不能引用先前覆蓋中新增的節點。此限制是必要的,因為覆蓋應用程式不會將覆蓋符號表與主 DT 符號表合併(不合併可以避免符號名稱衝突以及覆蓋之間依賴關係的複雜化)。

範例:無效的疊加

在此範例中, overlay_2.dts引用由overlay_1.dts新增的節點e 。將overlay_1套用到主DT 後,如果嘗試將overlay_2套用到結果DT,則覆寫應用程式將會失敗,並顯示符號e不存在於基本DT 的符號表中的錯誤。

主文件覆蓋_1.dts覆蓋_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中的property prop值(由overlay_1.dts設定)將被overlay_2.dts設定的值覆寫。

主文件覆蓋_1.dts覆蓋_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 分區結構的詳細信息,請參閱 source.android.com 上的設備樹覆蓋

驗證 DTBO 分區

您可以使用 VTS 驗證以下內容:

  • 核心命令列參數androidboot.dtbo_idx是否存在(透過檢查Init是否已自動設定對應的ro.boot.dtbo_idx系統屬性)。
  • ro.boot.dtbo_idx系統屬性的有效性(透過檢查該屬性是否指定至少一個有效的 DTBO 映像索引)。
  • DTBO 分區的有效性(也驗證 DTBO 分區中應用於基礎 DT 的覆蓋)。
  • 產生的 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";
	};
};