dts結構及其編譯方法
一:主要問題
1,需要了解dtsi與dts的關係
2,dts的結構模型
3,dts是如何被編譯的,以及編譯後會生成乙個什麼檔案.
二:參考文字
.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 \在linux下,我們可以單獨編譯devicetree檔案。當我們在linux核心下執行makedtbs時,若我們之前選擇了arch_vexpress,上述.dtb都會由對應的.dts編譯出來。因為arch/arm/makefile中含有乙個dtbs編譯target專案。vexpress-v2p-ca9.dtb \
vexpress-v2p-ca15-tc1.dtb \
vexpress-v2p-ca15_a7.dtb \
xenvm-4.2.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/core/makefile"中用下面語句使它被編入boot.img。$(build-dtimage-target)
ifeq ($(strip $(board_kernel_separated_dt)),true)internal_bootimage_args += --dt $(installed_dtimage_target)
bootimage_extra_deps s:= $(installed_dtimage_target)
endif
DT系列一 DTS結構及其編譯方法
dts 結構及其編譯方法 一 主要問題 1,需要了解dtsi 與dts 的關係2,dts 的結構模型 3,dts 是如何被編譯的,以及編譯後會生成乙個什麼檔案.二 參考文字 dts 檔案是一種ascii 文字格式的devicetree 描述。基本上,在armlinux 內,乙個.dts 檔案對應乙個...
dts 編譯過程 DTS結構及其編譯方法
一 主要問題 1,需要了解dtsi與dts的關係 2,dts的結構模型 3,dts是如何被編譯的,以及編譯後會生成乙個什麼檔案.二 參考文字 1,dts device tree source dts檔案是一種ascii文字格式的devicetree描述。基本上,在armlinux內,乙個.dts檔案...
DTS結構及其編譯方法
dts 結構及其編譯方法 一 主要問題 1,需要了解dtsi 與dts 的關係2,dts 的結構模型 3,dts 是如何被編譯的,以及編譯後會生成乙個什麼檔案.二 參考文字 dts 檔案是一種ascii 文字格式的devicetree 描述。基本上,在armlinux 內,乙個.dts 檔案對應乙個...