Linux DTS 设备树源码
1. 简介
-
概念:设备树(Device Tree),将这个词分开就是“设备”和“树”,描述设备树的文件叫做 DTS(Device Tree Source),这个 DTS 文件采用树形结构描述板级设备,也就是开发板上的设备信息,比如 CPU 数量、 内存基地址、IIC 接口上接了哪些设备、SPI 接口上接了哪些设备等等。如下图所示

-
树的主干就是系统总线,IIC 控制器、GPIO 控制器、SPI 控制器等都是接 到系统主线上的分支。IIC 控制器有分为 IIC1 和 IIC2 两种,其中 IIC1 上接了 FT5206 和 AT24C02 这两个 IIC 设备,IIC2 上只接了 MPU6050 这个设备。DTS 文件的主要功能就是按图所示的结构来描述板子上的设备信息。
-
DTS 是为 Linux 提供一种硬件信息的描述方法,以此代替源码中的 硬件编码 (hard code)。DTS 即 Device Tree Source 设备树源码, Device Tree 是一种描述硬件的数据结构,起源于 OpenFirmware (OF). 在 Linux 2.6 中, ARM 架构的板级硬件细节过多的被硬编码在 arch/arm/plat-xxx 和 arch/arm/mach-xxx (比如板上的 platform 设备,resource, i2c_board_info, spi_board_info 以及各种硬件的 platform_data), 这些板级细节代码对内核来讲只不过是垃圾代码。而采用 Device Tree 后, 许多硬件的细节可以直接透过它传递给 Linux,而不再需要在 kernel 中 进行大量的冗余编码。
-
DTS设备树描述文件中什么代表总线,什么代表设备
- 设备:一个含有compatible属性的节点就是一个设备
- 总线:包含一组设备节点的父节点即为总线
1.1 引入DTS的原因
- 对ARM平台的相关code做出如下相关规范调整,这个也正是引入DTS的原因:
- ARM的核心代码仍然保存在arch/arm目录下
- ARM SoC core architecture code保存在arch/arm目录下
- ARM SOC的周边外设模块的驱动保存在drivers目录下
- ARM SOC的特定代码在arch/arm/mach-xxx目录下
- ARM SOC board specific的代码被移除,由DeviceTree机制来负责传递硬件拓扑和硬件资源信息。
- 本质上,Device Tree改变了原来用hardcode方式将HW 配置信息嵌入到内核代码的方法,改用bootloader传递一个DB的形式。
- 如果我们认为kernel是一个black box,那么其输入参数应该包括:
- 识别platform的信息
- runtime的配置参数
- 设备的拓扑结构以及特性
- 对于嵌入式系统,在系统启动阶段,bootloader会加载内核并将控制权转交给内核,此外, 还需要把上述的三个参数信息传递给kernel,以便kernel可以有较大的灵活性。在linux kernel中,Device Tree的设计目标就是如此。
1.2 文件格式
| 缩写 | 描述 |
|---|---|
| DTS(.dts) | 设备树源文件(描述板级信息:开发板上有哪些 IIC 设备、SPI 设备等) |
| DTS(.dtb) | 设备树编译文件 |
| .dtsi | 设备树头文件(描述SOC级信息:CPU 架构、主频、外设寄存器地址范围等) |
| DTC | 将.dts 编译为.dtb:DTC的源代码位于内核的scripts/dtc目录,在Linux内核使能了Device Tree的情况下, 编译内核的时候主机工具dtc会被编译出来,对应scripts/dtc/Makefile中的“hostprogs-y := dtc”这一hostprogs编译target。 在Linux内核的arch/arm/boot/dts/Makefile中,描述了当某种SoC被选中后,哪些.dtb文件会被编译出来 |
- 设备树相关文件均在 arch/arm/boot/dts/ 文件夹
- DTC 工具源码在 Linux 内核的 scripts/dtc 目录下
- DTC 工具依赖于 dtc.c、flattree.c、fstree.c 等文件,最终编译并链接出 DTC 这个主机文件
- 在 arch/arm/boot/dts/Makefile 中新增需要编译的DTS文件。
- 如果要编译 DTS 文件的话只需要进入到 Linux 源码根目录下,然后执行如下命令:
- make all:编译 Linux 源码中的所有东西,包括 zImage,.ko 驱动模块以及设备 树
- make dtbs:仅编译设备树
2. DTS语法
- DTS中常用符号的含义
| 符号 | 描述 |
|---|---|
| / | 根节点 |
| @ | 如果设备有地址,则由此符号指定 |
| & | 引用节点 |
| : | 冒号前的label是为了方便引用给节点起的别名,此label一般使用为&label |
| , | 属性名称中可以包含逗号。如compatible属性的名字 组成方式为”[manufacturer], [model]”,加入厂商名是为了避免重名。自定义属性名中通常也要有厂商名,并以逗号分隔。 |
| # | #并不表示注释。如 #address-cells ,#size-cells 用来决定reg属性的格式 |
| 空属性并不一定表示没有赋值。如 interrupt-controller 一个空属性用来声明这个node接收中断信号数据类型 | |
| ”” | 引号中的为字符串,字符串数组:”strint1”,”string2”,”string3” |
| < > | 尖括号中的为32位整形数字,整形数组<12 3 4> |
| [ ] | 方括号中的为32位十六进制数,十六机制数据[0x11 0x12 0x13] 其中0x可省略 |
2.1 .dtsi头文件
- 在 .dts 设备树文件中,可以通过“#include ”来引用 .h 、 .dtsi 和 .dts 文件。
- .dtsi 文件用于描述 SOC 的内部外设信息,比如 CPU 架构、主频、外设寄存器地址范围,比如 UART 、 IIC 等等。
2.2 设备节点
- 设备树是采用树形结构来描述板子上的设备信息的文件,每个设备都是一个节点,叫做设备节点,每个节点都通过一些属性信息来描述节点信息,属性就是 键值对。每个节点都有不同属性,不同的属性又有不同的内容,属性都是键值对,值可以为空或任意的字节流。
- .dts举例说明
/ {
aliases {
can0 = &flexcan1;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
compatible = "arm,cortex-a7";
device_type = "cpu";
reg = <0>;
};
};
intc: interrupt-controller@00a01000 {
compatible = "arm,cortex-a7-gic";
#interrupt-cells = <3>;
interrupt-controller;
reg = <0x00a01000 0x1000>,
<0x00a02000 0x100>;
};
}
- “/”是根节点,每个设备树文件只有一个根节点。
2.2.1 设备树中节点命名格式
- 节点标签:节点名@设备的地址或寄存器首地址
label: node-name@unit-address
// e.g.:
cpu0:cpu@0
2.2.2 设备树源码中常用的几种数据类型
1) 字符串
compatible ="arm,cortex-a7";
上述代码设置 compatible 属性的值为字符串“arm,cortex-a7”。

本文详细介绍了Linux DTS设备树的概念、文件格式、语法及常见操作函数等内容。DTS设备树是一种描述硬件的数据结构,用于替代内核中的硬件编码,提高系统的灵活性和可维护性。
最低0.47元/天 解锁文章
4万+

被折叠的 条评论
为什么被折叠?



