如何看下面这张图:
1)从根节点开始看起,即 /
2)在根节点中有属性以及设备节点名称
3)属性的格式有两种形式,当property-name = value时,value的取值有三种形式
4)设备节点(child nodes)的格式

总结:
(1) 语法:
Devicetree node格式:
[label:] node-name[@unit-address] {
      [properties definitions]
      [child nodes]
};
Property格式1:
[label:] property-name = value;
Property格式2(没有值):
[label:] property-name;
Property取值只有3种: 
arrays of cells(1个或多个32位数据, 64位数据使用2个32位数据表示), 
string(字符串), 
bytestring(1个或多个字节)
示例: 
a. Arrays of cells : cell就是一个32位的数据
interrupts = <17 0xc>;
b. 64bit数据使用2个cell来表示:
clock-frequency = <0x00000001 0x00000000>;
c. A null-terminated string (有结束符的字符串):
compatible = "simple-bus";
d. A bytestring(字节序列) :
local-mac-address = [00 00 12 34 56 78];  // 每个byte使用2个16进制数来表示
local-mac-address = [000012345678];       // 每个byte使用2个16进制数来表示
e. 可以是各种值的组合, 用逗号隔开:
compatible = "ns16550", "ns8250";
example = <0xf00f0000 19>, "a strange property format";
(2) 
DTS文件布局(layout):
/dts-v1/;
[memory reservations]    // 格式为: /memreserve/ <address> <length>;
/ {
      [property definitions]
      [child nodes]
};
(3) 特殊的、默认的属性:
a. 根节点:
#address-cells     // 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)
#size-cells          // 在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size)
例子:
#address-cells = <1>;
	#size-cells = <1>;
		
	memory@30000000 {
		  device_type = "memory";
		  reg =  <0x30000000 0x4000000>;  
	};
在子节点的reg属性中,0x30000000表示地址,0x4000000来表示大小。我凭什么知道在reg中用一个32位整数来描述地址,一个32位整数来描述大小。就是通过
#address-cells = <1>;
#size-cells = <1>;
进行指定的。
compatible     // 定义一系列的字符串, 用来指定内核中哪个machine_desc可以支持本设备
                            // 即这个板子兼容哪些平台 
                            // uImage : smdk2410 smdk2440 mini2440     ==> machine_desc 。一个uImage可以支持多种单板,比如说smdk2410、smdk2440、mini2440。每种单板在内核中都有一个对应的machine_desc结构体,里面会有不同的初始化函数。因此利用compatible这个属性可以选择单板,让内核去执行对应的初始化函数。
举例:
compatible = "samsung,smdk2440"; 通过这样指定,内核就会去执行smdk2440中的初始化函数
compatible可以是一个或多个字符串。比如说compatible = "samsung,smdk2440" "samsung,smdk24xx"
smdk2440就更加具体,s3c24xx就比较广泛些,可以适配更多的单板。使用设备树时,优先去内核中寻找支持smdk2440的machine_desc,如果找不到的话,再去寻找支持smdk24xx的machine_desc。优先选择第一项,如果没有,再往后选择。
                 
model              // 咱这个板子是什么
                         // 比如有2款板子配置基本一致, 它们的compatible是一样的
                        // 那么就通过model来分辨这2款板子
b. /memory
device_type = "memory";   //这是约定俗称的,必须写这个。
reg             // 用来指定内存的地址、大小
c. /chosen
bootargs        // 内核command line参数, 跟u-boot中设置的bootargs作用一样
例子:
chosen {
		bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200";   //内核启动时的命令行参数
	};
d. /cpus
/cpus节点下有1个或多个cpu子节点, cpu子节点中用reg属性用来标明自己是哪一个cpu
所以 /cpus 中有以下2个属性:
#address-cells   // 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)
#size-cells        // 在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size)
                          // 必须设置为0
e. /cpus/cpu*
device_type = "cpu";
reg             // 表明自己是哪一个cpu
原文:https://www.cnblogs.com/-glb/p/11674707.html