編譯和驗證

您可以使用設備樹編譯器 (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 結果

驗證可以幫助您識別在將覆蓋 DT 放置在主 DT 上時可能發生的錯誤。在更新目標之前,您可以通過在.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,z報告xyz作為設備樹覆蓋 (DTO) 的從零開始的索引,來自引導加載程序應用(按該順序)到基的 DTBO 分區設備樹 (DT)。

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

示例:無效的疊加層

在本例中, overlay_2.dts指的是由overlay_1.dts添加的節點e 。在將overlay_1應用到主 DT 之後,如果嘗試將overlay_2應用到結果 DT,則覆蓋應用程序將失敗,並顯示符號e不存在於基本 DT 的符號表中的錯誤。

主文件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中的屬性prop的值(由overlay_1.dts設置)被overlay_2.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 分區結構的詳細信息,請參閱 source.android.com 上的Device Tree Overlays

驗證 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";
	};
};