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 \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
專案。
.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
。對於第一種方式,會用
中定義的下面規則編出
"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是如何被編譯的,以及編譯後會生成乙個什麼檔案.二 參考文字 1,dts device tree source 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...