DT(Device Tree):是一种描述硬件的数据结构,由一系列被命名的结点(node)和属性(property)组成
DTS:设备树源
1:设备树的由来
在Linux内核源码的ARM体系结构引入设备树之前,相关的BSP代码充斥了大量的平台设备(PlatformDevice)代码,而这些代码大多都是重复的、杂乱的。之前的内核移植工作有很大一部分就是在复制一份BSP代码,并修改BSP代码中和目标板中与特定硬件相关的平台设备信息。这使得ARM体系结构的代码维护者和内核维护者在发布一个新版本内核的一段时间内有大量的工作要做。于是设备树被ARM社区采用。
设备树最初是由开放固件(OpenFirmware)使用的,用来向一个客户程序(通常是一个操作系统)传送数据的通信方法中的一部分内容。在运行时,客户程序通过设备树发现设备的拓扑结构,这样就不需要把硬件信息硬编码到程序中。
2:设备树的目的
设备树是一个描述硬件的数据结构,它并没有什么神奇的地方,也不能把所有硬件配置的问题都解决掉。它只是提供了一种语言,将硬件配置从Linux内核源码中提取出来。设备树使得目标板和设备变成数据驱动的,它们必须基于传递给内核的数据进行初始化,而不是像以前一样采用硬编码的方式。理论上,这种方式可以带来较少的代码重复率,使单个内核镜像能够支持很多硬件平台。
Linux使用设备树有以下三个原因
(1)平台识别
这点是最为重要的,内核使用设备树中的数据去识别特定机器(目标板,在内核中称为machine)。最完美的情况是,内核应该与特定硬件平台无关,因为所有硬件平台的细节都是由设备树来描述的。然而,硬件平台并不是完美的,所以内核必须在早期初始化阶段识别机器,这样内核才有机会运行与特定机器相关的初始化序列。
(2)实时配置
在大多数情况下,设备树是固件与内核之间进行数据通信的唯一方式,所以也用于传递实时或配置数据给内核,比如内核参数、initrd镜像的地址等。
大多数这种数据被包含在设备树的/chosen 节点,形如:
chosen { bootargs = "console = ttys0,115200 loglevel = 8";
initrd-start = <0xc8000000>;
initrd-end = <0xc8200000>;
};
bootargs属性包含内核参数,initrd-*属性定义了initrd文件的首地址和大小。chosen节点也有可能包含任意数量的描述平台特殊配置的属性。
(3)设备植入
经过板子识别和早期配置数据解析之后,内核进一步进行初始化。期间,unflatten_device_tree函数被调用,将设备树的数据转换成一种更有效的实时形式。
3.设备树的使用
(1)基本数据格式
在Linux中,设备树文件的类型 有.dts、 .dtsi 和 .dtb。其中, .dtsi是被包含的设备树源文件,类似于C语言中的头文件;.dts是设备树源文件,可以包含其他 .dtsi 文件, 由dtc编译生成 .dtb文件
设备树是一个包含节点和属性的简单树状结构。属性就是键值对,而节点可以同时包含属性和节点。下面就是一个.dts格式的简单设备树:
/{
node1 {
a-string-propety = "A string";
a-string-list-property = "first string", "second string";
a-byte-data-property = [0x01 0x23 0x34 0x56];
child-node1 {
first-child-property;
second-child-property = <1>;
a-string-property = "Hello, world";
};
child-node2 {
};
};
node2 {
an-empty-property;
a-cell-property = <1>; /* each number (cell) is a uint 32 */
child-node1 {
};
};
};
该设备树包含了下面的内容
①:一个单独的根节点:/
②:两个子节点:node1 和 node2
③:两个node1的子节点:child-node1 和 child-node2
④:一堆分散在设备树中的属性
其中,属性是简单的键值对,它的值可以为空或包含一个任意字节流。在设备树源文件有以下几个基本的数据表示形式。
文本字符串(无结束符):可以用双引号表示,如a-string-property = "A string"。
cells:32位无符号整数,用角括号限定,如second-child-property = <1>。
二进制数据:用方括号限定,如a-byte-data-property = [0x01 0x23 0x34 0x56]。
混合表示:使用逗号连在一起,如mixed-property = "a string",[0x01 0x23 0x45 0x67],<0x12345678>。
字符串列表:使用逗号连在一起,如string-list = "red fish","bule fish"。