1.写在前面
本文是本人在阅读了蜗窝科技的Device Tree三篇文章后的笔记,他的这几篇文章是我最近了解到的在Device Tree方面讲的比较深入细致的,非常感谢蜗窝科技为我们提供的学习机会,如果有需要,请你们去蜗窝科技。
2.Device Tree结构
kernel/arch/arm/boot/dts/skeleton.dtsi:
/ {
#address-cells = <1>;
#size-cells = <1>;
cpus { };
soc { };
chosen { };
aliases { };
memory { device_type = "memory"; reg = <0 0>; };
};
kernel/arch/arm/boot/dts/qcom/skeleton.dtsi:
#include "skeleton64.dtsi"
#include <dt-bindings/clock/msm-clocks-8953.h>
#include <dt-bindings/regulator/qcom,rpm-smd-regulator.h>
#include <dt-bindings/gpio/gpio.h>
/ {
model = "Qualcomm Technologies, Inc. MSM 8953";
compatible = "qcom,msm8953";
qcom,msm-id = <293 0x0>;
interrupt-parent = <&intc>;
chosen {
bootargs = "sched_enable_hmp=1 sched_enable_power_aware=1";
};
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
other_ext_mem: other_ext_region@0 {
compatible = "removed-dma-pool";
no-map;
reg = <0x0 0x83300000 0x0 0x3800000>;
};
modem_mem: modem_region@0 {
compatible = "removed-dma-pool";
no-map-fixup;
reg = <0x0 0x86c00000 0x0 0x5600000>;
};
reloc_mem: reloc_region@0 {
compatible = "removed-dma-pool";
no-map;
reg = <0x0 0x8c200000 0x0 0x1800000>;
};
venus_mem: venus_region@0 {
compatible = "shared-dma-pool";
reusable;
alloc-ranges = <0x0 0x80000000 0x0 0x10000000>;
alignment = <0 0x400000>;
size = <0 0x0800000>;
};
secure_mem: secure_region@0 {
compatible = "shared-dma-pool";
reusable;
alignment = <0 0x400000>;
size = <0 0x09800000>;
};
qseecom_mem: qseecom_region@0 {
compatible = "shared-dma-pool";
reusable;
alignment = <0 0x400000>;
size = <0 0x1000000>;
};
adsp_mem: adsp_region@0 {
compatible = "shared-dma-pool";
reusable;
size = <0 0x400000>;
};
dfps_data_mem: dfps_data_mem@90000000 {
reg = <0 0x90000000 0 0x1000>;
label = "dfps_data_mem";
};
cont_splash_mem: splash_region@0x90001000 {
reg = <0x0 0x90001000 0x0 0x13ff000>;
label = "cont_splash_mem";
};
gpu_mem: gpu_region@0 {
compatible = "shared-dma-pool";
reusable;
alloc-ranges = <0x0 0x80000000 0x0 0x10000000>;
alignment = <0 0x400000>;
size = <0 0x800000>;
};
};
aliases {
/* smdtty devices */
smd1 = &smdtty_apps_fm;
smd2 = &smdtty_apps_riva_bt_acl;
smd3 = &smdtty_apps_riva_bt_cmd;
smd4 = &smdtty_mbalbridge;
smd5 = &smdtty_apps_riva_ant_cmd;
smd6 = &smdtty_apps_riva_ant_data;
smd7 = &smdtty_data1;
smd8 = &smdtty_data4;
smd11 = &smdtty_data11;
smd21 = &smdtty_data21;
smd36 = &smdtty_loopback;
sdhc1 = &sdhc_1; /* SDC1 eMMC slot */
sdhc2 = &sdhc_2; /* SDC2 for SD card */
i2c1 = &i2c_1;
i2c2 = &i2c_2;
i2c3 = &i2c_3;
i2c5 = &i2c_5;
spi3 = &spi_3;
};
soc: soc { };
};
由上面的例子看出Device Tree有一下特点:
1.节点node
1.1每个node可以包含sub node和property/value;
1.2每个DTS都只有一个ROOT node;
1.3一个node可以有多个sub node,但只能有一个parent node;
1.4一个node可以包含多个property/value描述该node的具体信息;
1.5每个node用节点名字(node name)标识,节点名字的格式是node-name@unit-address。如果该node没有reg属性(后面会描述这个property),那么该节点名字中必须不能包括@和unit-address。
2.属性/值property/value
2.1一般属性:
属性值表示了该设备节点的具体特性,它的值是多样性的:
1)可能为空,即没有值的定义;
2)可能为32bit或64bit整数值(#size-cells = <2>)或者数组(reg = <0x0 0x86c00000 0x0 0x5600000>);
3)可能为string(label = "cont_splash_mem")或string list(compatible = "qcom,msm8953");
2.2特殊属性:
#address-cells = <1>;
#size-cells = <0>;
#类似number,#address-cells表示子节点中reg中的地址元素需要用多少个32bit值来表示,#size-cells表示子节点中reg中的大小元素需要用多少个32bit值来表示。
3.Device Tree source file语法
1.节点定义:
[label:] node-name[@unit-address] {
[properties definitions];
[child nodes];
};
2.节点引用:
1)直接引用:绝对路径,/node-name-1/node-name-2/node-name-N;
2)别名引用:所有别名被定义在节点aliases中;
3)lable引用:&lable;
3.属性定义:
property = value;
再次注意value的三种方式:
1)32bit unsigned integers:#size-cells = <2>;
2)binary data:binary-property = [0x01 0x23 0x45 0x67];
3)string/string list:device_type = "memory";
4.dts注释
dts支持c/c++类型注释,如下方式:
/* 多行注释 */
/*
dfps_data_mem: dfps_data_mem@90000000 {
reg = <0 0x90000000 0 0x1000>;
label = "dfps_data_mem";
};
*/
cont_splash_mem: splash_region@0x90001000 {
//单行注释
//reg = <0x0 0x90001000 0x0 0x13ff000>;
//label = "cont_splash_mem";
};
5.dts编译
dts的编译一般使用dtc工具,kernel源码中自带该工具,编译后在/script/dtc/目录下。
使用方法:
1.编译dts为dtb文件:
dtc -I dts -O dtb -o <dtbfilename> <dtsfilename>
2.反编译dtb为dts文件:
dtc -I dtb -O dts -o <dtsfilename> <dtbfilename>