dts 編譯過程 DTS結構及其編譯方法

2021-10-21 08:15:39 字數 3663 閱讀 2392

一、主要問題

1,需要了解dtsi與dts的關係

2,dts的結構模型

3,dts是如何被編譯的,以及編譯後會生成乙個什麼檔案.

二、參考文字

1,dts(device tree source)

.dts檔案是一種ascii文字格式的devicetree描述。基本上,在armlinux內,乙個.dts檔案對應乙個arm的machine,一般放置在核心的arch/arm/boot/dts/目錄。由於乙個soc可能對應多個machine(乙個soc可以對應多個產品和電路板),勢必這些.dts檔案需包含許多共同的部分。linux核心為了簡化,把soc公用的部分或者多個machine共同的部分一般提煉為.dtsi,類似於c語言的標頭檔案。其他的machine對應的.dts就include這個.dtsi。

2,dts的結構模型

為了了解devicetree的結構,我們首先給出乙個devicetree的示例:

/o device-tree

|- name ="device-tree"

|- model ="myboardname"

|-compatible = "myboardfamilyname"

|- #address-cells = <2>

|-#size-cells = <2>

|-linux,phandle = <0>

o cpus

| | - name = "cpus"

| | - linux,phandle = <1>

| |- #address-cells = <1>

| | -#size-cells = <0>

| o powerpc,970@0

| |- name ="powerpc,970"

| |-device_type = "cpu"

| |-reg = <0>

| |-clock-frequency = <0x5f5e1000>

| |- 64-bit

| |- linux,phandle =<2>

o memory@0

| |- name ="memory"

| |- device_type= "memory"

| |- reg =<0x00000000 0x00000000 0x00000000 0x20000000>

| |- linux,phandle = <3>

o chosen

|- name = "chosen"

|- bootargs = "root=/dev/sda2"

|- linux,phandle = <4>

從上圖中可以看出,devicetree的基本單元是node。這些node被組織成樹狀結構,除了rootnode,每個node都只有乙個parent。乙個devicetree檔案中只能有乙個rootnode。每個node中包含了若干的property/value來描述該node的一些特性。每個node用節點名字(nodename)標識,節點名字的格式是node-name@unit-address。如果該node沒有reg屬性(後面會描述這個property),那麼該節點名字中必須不能包括@和unit-address。unit-address的具體格式是和裝置掛在哪個bus上相關。例如對於cpu,其unit-address就是從0開始編址,以此加一。而具體的裝置,例如乙太網控制器,其unit-address就是暫存器位址。rootnode的nodename是確定的,必須是「/」。

3,dts是如何被編譯的,以及編譯後會生成乙個什麼檔案。

dtc(device tree compiler)

dtc是將.dts編譯為.dtb的工具。dtc的源**位於核心的scripts/dtc目錄,在linux核心使能了devicetree的情況下,編譯核心時,主機工具dtc會被編譯出來,對應scripts/dtc/makefile中的「hostprogs-y:= dtc」這一hostprogs編譯target。

在linux核心的arch/arm/boot/dts/makefile中,描述了當某種soc被選中後,哪些.dtb檔案會被編譯出來。舉例如下:

如與vexpress對應的.dtb包括:

dtb-$(config_arch_vexpress) += vexpress-v2p-ca5s.dtb \

vexpress-v2p-ca9.dtb \

vexpress-v2p-ca15-tc1.dtb \

vexpress-v2p-ca15_a7.dtb \

xenvm-4.2.dtb

在linux下,我們可以單獨編譯devicetree檔案。當我們在linux核心下執行makedtbs時,若我們之前選擇了arch_vexpress,上述.dtb都會由對應的.dts編譯出來。因為arch/arm/makefile中含有乙個dtbs編譯target專案。

devicetree blob (.dtb)

.dtb是.dts被dtc編譯後的二進位制格式的devicetree描述,可由linux核心解析。通常在我們為電路板製作nand、sd啟動image時,會為.dtb檔案單獨留下乙個很小的區域以存放之,之後bootloader在引導kernel的過程中,會先讀取該.dtb到記憶體。

源**體現

有兩種方式使用dt。第一種可包含多個dtb,編入dt.img,放入boot.img。第二種只包含乙個dtb,直接追加到kernelimage後面,放入boot.img。

dtc編譯在kernel/androidkernel.mk中定義。先用定義"dts_names"變數,它的每個entry(記為"dts_name"變數,下面的$$arch)中可能有arch和rev兩部分,和.config中相關配置有關,用下面方法找出。

while (<>) print $$arch;

得到上述"dts_names"變數,用"$(dts_name)*.dts"方式去"kernel/arch/arm/boot/dts/"下匹配。見下面的定義,其中"cat"命令就是生成帶dt的kernelimage。

mkdir -p $(kernel_out)/arch/arm/boot;\

$(foreach dts_name, $(dts_names), \

$(foreach d, $(dts_files), \

$(dtc) -p 1024 -o dtb -o $(call dtb_file,$(d)) $(d); \

cat $(kernel_zimg) $(call dtb_file,$(d)) > $(call zimg_file,$(d));))

endef

第二種方式沒看到後續如何放入boot.img。對於第一種方式,會用"device/qcom/common/generate_extra_images.mk"中定義的下面規則編出"dt.img",

$(installed_dtimage_target): $(dtbtool) $(installed_kernel_target)

$(build-dtimage-target)

在"build/core/makefile"中用下面語句使它被編入boot.img。

ifeq ($(strip $(board_kernel_separated_dt)),true)

internal_bootimage_args += --dt $(installed_dtimage_target)

bootimage_extra_deps   s:= $(installed_dtimage_target)

endif

DTS結構及其編譯方法

dts 結構及其編譯方法 一 主要問題 1,需要了解dtsi 與dts 的關係2,dts 的結構模型 3,dts 是如何被編譯的,以及編譯後會生成乙個什麼檔案.二 參考文字 dts 檔案是一種ascii 文字格式的devicetree 描述。基本上,在armlinux 內,乙個.dts 檔案對應乙個...

DT系列一 DTS結構及其編譯方法

dts 結構及其編譯方法 一 主要問題 1,需要了解dtsi 與dts 的關係2,dts 的結構模型 3,dts 是如何被編譯的,以及編譯後會生成乙個什麼檔案.二 參考文字 dts 檔案是一種ascii 文字格式的devicetree 描述。基本上,在armlinux 內,乙個.dts 檔案對應乙個...

DT系列一 DTS結構及其編譯方法

dts結構及其編譯方法 一 主要問題 1,需要了解dtsi與dts的關係 2,dts的結構模型 3,dts是如何被編譯的,以及編譯後會生成乙個什麼檔案.二 參考文字 dts檔案是一種ascii文字格式的devicetree描述。基本上,在armlinux內,乙個.dts檔案對應乙個arm的machi...