设备树
设备树简介
设备树是一种描述硬件的数据结构,它起源于OpenFirmware(OF)。
在Linux 2.6中, ARM架构的板极硬件细节过多地被硬编码在arch/arm/plat-xxx和arch/arm/mach-xxx中,采用设备树后,许多硬件的细节可以直接通过它传递给Linux,而不再需要在内核中进行大量的冗余编码。
DTS、DTB、DTC
DTS:
1.dts文件是设备树的源文件。
2 由于一个SoC可能对应多个设备,这些.dst文件可能包含很多共同的部分,共同的部分一般被提炼为一个.dtsi文件,这个文件相当于C语言的头文件。
3 可针对单独设备编写对应dts文件,调用.dtsi;
DTC:
DTC是将.dts编译为.dtb的工具,相当于gcc。
DTB:
.dtb文件是 .dts 被 DTC 编译后的二进制格式的设备树文件,它可以被linux内核解析。
make dtbs
DTS语法
.dts.dtsi
和 C 语言一样,设备树也支持头文件,设备树的头文件扩展名为 .dtsi;同时也可以像C 语言一样包含 .h头文件;
例如:(代码来源 linux-4.15/arch/arm/boot/dts/s3c2416.dtsi)
#include <dt-bindings/clock/s3c2443.h>
#include "s3c24xx.dtsi"
注:.dtsi 文件一般用于描述 SOC 的内部外设信息,比如 CPU 架构、主频、外设寄存器地址范围,比如 UART、 IIC 等等。
设备节点及属性
在设备树中节点命名格式如下:
node-name@unit-address
node-name:是设备节点的名称,为ASCII字符串,节点名字应该能够清晰的描述出节点的功能,比如“uart1”就表示这个节点是UART1外设;unit-address:一般表示设备的地址或寄存器首地址,如果某个节点没有地址或者寄存器的话 “unit-address” 可以不要;
注:根节点没有node-name 或者 unit-address,它被定义为 /。
节点属性
设备树中的每个节点都有描述节点特征的属性。属性由名称和值组成
节点属性
compatible 属性
compatible 属性也叫做 “兼容性” 属性,这是非常重要的一个属性!compatible 属性的值是一个字符串列表, compatible 属性用于将设备和驱动绑定起来。字符串列表用于选择设备所要使用的驱动程序。compatible 属性值的推荐格式:
"manufacturer,model"
① manufacturer : 表示厂商;
② model : 一般是模块对应的驱动名字。
注:一般驱动程序文件都会有一个 OF 匹配表,此 OF 匹配表保存着一些 compatible 值,如果设备节点的 compatible
属性值和 OF 匹配表中的任何一个值相等,那么就表示设备可以使用这个驱动。可通过了解驱动模型获取该知识点
model 属性
model 属性值也是一个字符串,一般 model 属性描述设备模块信息,比如名字什么的,例如:
model = "Samsung S3C2416 SoC";
phandle 属性
phandle属性为devicetree中唯一的节点指定一个数字标识符,节点中的phandle属性,它的取值必须是唯一的(不要跟其他的phandle值一样),例如:
pic@10000000 {
phandle = <1>;
interrupt-controller;
};
another-device-node {
interrupt-parent = <1>; // 使用phandle值为1来引用上述节点
};
注:DTS中的大多数设备树将不包含显式的phandle属性,当DTS被编译成二进制DTB格式时,DTC工具会自动插入phandle属性。
status 属性
status 属性看名字就知道是和设备状态有关的, status 属性值也是字符串,字符串是设备的状态信息,可选的状态如下表所示:
status值 | 描述 |
---|
#address-cells 和 #size-cells
#address-cells 和 #size-cells的值都是无符号 32 位整型,可以用在任何拥有子节点的设备中,用于描述子节点的地址信息。
#address-cells 属性值决定了子节点 reg 属性中地址信息
#size-cells 属性值决定了子节点 reg 属性中长度信息
#address-cells 和 #size-cells 表明了子节点应该如何编写 reg 属性值,一般 reg 属性都是和地址有关的内容,和地址相关的信息有两种:起始地址和地址长度,reg 属性的格式一为:
reg = <address1 length1 address2 length2 address3 length3……>
soc {
#address-cells = <2>;
#size-cells = <1>;
serial {
compatible = "xxx";
reg = <0x4600 0x5000 0x100>; /*地址信息是:0x00004600 00005000,长度信息是:0x100*/
};
};