设备树简介
复制自https://www.cnblogs.com/aaronLinux/p/5496559.html#t1

1、设备树基本概念及作用

在内核源码中,存在大量对板级细节信息描述的代码。这些代码充斥在/arch/arm/plat-xxx和/arch/arm/mach-xxx目录,对内核而言这些platform设备、resource、i2c_board_info、spi_board_info以及各种硬件的platform_data绝大多数纯属垃圾冗余代码。为了解决这一问题,ARM内核版本3.x之后引入了原先在Power PC等其他体系架构已经使用的Flattened Device Tree。
“A data structure by which bootloaders pass hardware layout to Linux in a device-independent manner, simplifying hardware probing.”开源文档中对设备树的描述是,一种描述硬件资源的数据结构,它通过bootloader将硬件资源传给内核,使得内核和硬件资源描述相对独立(也就是说*.dtb文件由Bootloader读入内存,之后由内核来解析)。
Device Tree可以描述的信息包括CPU的数量和类别、内存基地址和大小、总线和桥、外设连接、中断控制器和中断使用情况、GPIO控制器和GPIO使用情况、Clock控制器和Clock使用情况。
另外,设备树对于可热插拔的热备不进行具体描述,它只描述用于控制该热插拔设备的控制器。
设备树的主要优势:对于同一SOC的不同主板,只需更换设备树文件.dtb即可实现不同主板的无差异支持,而无需更换内核文件。
注:要使得3.x之后的内核支持使用设备树,除了内核编译时需要打开相对应的选项外,bootloader也需要支持将设备树的数据结构传给内核。

2、设备树的基本语法

在节点的{}里面是描述该节点的属性(property),即设备的特性。它的值是多样化的:
它可以是字符串string
它也可以是32 bit unsigned integers,如cell整形用<>表示
它也可以是binary data,如十六进制用[]表示
它也可能是空

2.1 chosen node

  1. chosen {
  2. bootargs = "tegraid=40.0.0.00.00 vmalloc=256M video=tegrafb console=ttyS0,115200n8 earlyprintk";
  3. };

chosen node 主要用来描述由系统指定的runtime parameter,它并没有描述任何硬件设备节点信息。它的父节点必须是根节点”/“

2.2 aliases node

aliases {
i2c6 = &pca9546_i2c0;
i2c7 = &pca9546_i2c1;
i2c8 = &pca9546_i2c2;
i2c9 = &pca9546_i2c3;
};

aliases node用来定义别名,类似C++中引用。
.dtsi中大多默认为设备为disable,然后在.dts中将其enable,进行重写使能。status=”okay”为使能。

2.3 memory node

memory {
device_type = "memory";
reg = <0x00000000 0x20000000>; /* 512 MB */
};

reg里的前者是开始地址,后者是大小。一般在.dts中不对memory进行描述。而是通过bootargs中类似521M@0x00000000的方式传递给内核。

2.4Reg属性

在device node 中,reg是描述memory-mapped IO register的offset和length。子节点的reg属性address和length长度取决于父节点对应的#address-cells和#size-cells的值。
1.png
设备节点的名称格式node-name@unit-address,节点名称用node-name唯一标识,为一个ASCII字符串。其中@unit-address为可选项,可以不作描述。
2.5 compatible属性
compatible对应的是字符串list从左到右的匹配驱动,如果没有就往右匹配下一个。
2.6 interrupts属性
3.png

2.png
设备节点通过interrupt-parent来指定它所依附的中断控制器,当节点没有指定interrupt-parent时,则从parent节点中继承。上面例子中,root节点的interrupt-parent = <&mic>。这里使用了引用,即mic引用了②中的inrerrupt-controller @40008000;root节点的子节点并没有指定interrupt-controller,如ahb、fab,它们均使用从根节点继承过来的mic,即位于0x40008000的中断控制器。

2.7 ranges属性

ranges属性为地址转换表,这在pcie中使用较为常见,它表明了该设备在到parent节点中所对用的地址映射关系。ranges格式长度受当前节点#address-cell、parent节点#address-cells、当前节点#size-cell所控制。顺序为ranges=<前节点#address-cell, parent节点#address-cells , 当前节点#size-cell。
注:对于相同名称的节点,dtc会根据定义的先后顺序进行合并,其相同属性,取后定义的那个。