1 什么是设备树
设备树(Device Tree)是一种在嵌入式系统中描述硬件和设备的数据结构。它用于描述和传递硬件平台的信息,包括处理器、外设、中断控制器、内存、时钟和其他硬件组件的配置和连接关系。
设备树以树形结构组织,包括根节点和子节点。每个节点都有一个类型、属性和子节点。节点的类型用于指定设备或者设备的部分,属性则用于描述该设备的特性、资源需求和配置选项。设备树使用标准的文本格式(通常是以.dts或者.dtb文件扩展名的文件)或者二进制格式(.dtb文件)表示。
2 设备树的作用意义
设备树的主要作用是描述硬件平台的配置和连接信息,使得Linux内核能够根据设备树来动态配置和初始化硬件设备。通过读取设备树,Linux内核可以自动识别和配置连接到系统中的硬件设备,加载相应的驱动程序,并完成设备的初始化过程。这使得设备驱动的开发和移植变得更加灵活和通用。
设备树的使用大量应用于嵌入式系统和嵌入式Linux平台,特别是在ARM架构的系统中得到广泛应用。设备树允许硬件平台和设备驱动的开发人员分离,使得硬件和软件可以独立开发和维护,极大地简化了系统的移植和维护工作。同时,设备树也为开发工具、编译器和操作系统内核提供了一致性的接口和通信方式,促进了嵌入式系统的交互和兼容性。
3 设备树中设备名称
设备树的设备名称通常由硬件厂商定义。在设备树中,每个设备节点都有一个"compatible"属性,这个属性用来指定设备的名称。通常,设备的名称是根据硬件的型号或者厂商的命名规范来确定的。例如,一个设备的名称可以是"vendor,device-model"的形式,其中"vendor"表示设备的厂商名称,"device-model"表示设备的型号。具体的命名规范可以根据硬件厂商的规定来确定。
4 主要语法
- 设备树文件以`.dts`或`.dtsi`为扩展名。
- 设备树文件使用`/dts-v1/`作为文件的第一行。
- 使用`/include/`来包含其他设备树文件。
- 使用`/memreserve/`来保留内存区域。
- 使用`/aliases/`来定义设备别名。
- 使用`/chosen/`来指定选定的设备。
- 使用`/configurations/`来定义不同的配置。
- 使用`/extable/`来定义异常表。
- 使用`/cpus/`来描述CPU信息。
- 使用`/soc/`来描述SoC(系统片上组件)。
- 使用`/bus/`来描述总线。
- 使用`/interrupt-controller/`来描述中断控制器。
- 使用`/timer/`来描述定时器。
- 使用`/gpio/`来描述GPIO(通用输入输出)。
- 使用`/regulator/`来描述电源管理。
- 使用`/i2c/`、`/spi/`和`/pwm/`来描述I2C、SPI和PWM总线。
- 使用`/i2c@`、`/spi@`和`/pwm@`来描述I2C、SPI和PWM设备。
- 使用`/uart@`和`/sdhci@`来描述串口设备和SD卡接口。
- 使用`/memory/`来描述内存。
- 使用`/display/`来描述显示设备。
- 使用`/sound/`来描述声音设备。
- 使用`/network/`来描述网络设备。
ps:chosen属性
1. bootargs:用来设置内核启动参数,可以指定一些内核启动相关的选项。
2. stdout-path:用来指定标准输出设备的路径,例如串口地址。
3. bootcmd:用来指定系统启动时自动执行的命令。
4. linux,initrd-start和linux,initrd-end:用来指定内核映像文件的起始地址和结束地址。
5. linux,initrd-size:用来指定内核映像文件的大小。
6. linux,bootargs:与bootargs类似,用来设置内核启动参数。 这些属性可以根据系统的需求进行自定义,用于配置和描述系统的一些特性。它们是设备树中非常重要的一部分,有助于系统的初始化和配置。
5 设备树格式
设备树使用的是一种类似于XML的语法,主要包含以下几部分内容:
- /dts-v1/:指定设备树文件的版本。
- /{...}/:定义设备树的根节点,包含所有设备的描述。
- compatible:用于描述设备的兼容性,通常使用字符串来指定设备的型号、厂商等信息。
- reg:指定设备的物理地址和大小。
- interrupts:描述设备的中断信息。
- clocks:指定设备所使用的时钟源。
- gpio:描述设备的GPIO(通用输入输出)配置。
- status:指定设备的状态,如"okay"表示设备可用,"disabled"表示设备不可用。
- phandle和linux,phandle:用于设备节点之间的引用和绑定,以实现设备之间的互联。
比如
&fpd_dma_chan8 {
status = "okay";
};
&gpio {
emio-gpio-width = <32>;
gpio-mask-high = <0x0>;
gpio-mask-low = <0x5600>;
status = "okay";
};
&i2c0 {
status = "okay";
clock-frequency = <400000>;
scl-gpios = <&gpio 38 GPIO_ACTIVE_HIGH>;
sda-gpios = <&gpio 39 GPIO_ACTIVE_HIGH>;
// rtc@68 {
// compatible = "dallas,ds1337";
// reg = <0x68>;
// };
eeprom@50 {
compatible = "atmel,24c02";
/* compatible = "at24,24c02"; */
reg = <0x50>;
};
};
6 设备树的节点类型
- 根节点(root):树的顶层节点,代表整个设备树。
- 设备节点(device):代表硬件设备,包含设备的属性和寄存器信息。
- 总线节点(bus):代表硬件总线,包含总线的属性和连接的设备。
- 中断控制器节点(interrupt-controller):代表硬件中断控制器,包含中断控制器的属性和中断信号。
- 内存控制器节点(memory-controller):代表内存控制器,包含内存控制器的属性和地址信息。
- 时钟控制器节点(clock-controller):代表时钟控制器,包含时钟控制器的属性和时钟信号。
- 电源控制节点(power-controller):代表电源控制器,包含电源控制器的属性和电源状态。
- 快速消息传递节点(mailbox):代表快速消息传递机制,用于进程间通信。
- 中央处理器节点(cpu):代表中央处理器,包含处理器的属性和中断控制器关联。
- 定时器节点(timer):代表硬件定时器,包含定时器的属性和中断信号。
- 时钟节点(clock):代表时钟源,包含时钟的频率和模式。
- DMA控制器节点(dma-controller):代表Direct Memory Access(DMA)控制器,用于设备之间的高速数据传输。
7 设备树的默认的特殊属性
- compatible:指定设备的兼容性,用于匹配设备和驱动程序之间的关系。驱动程序根据设备树节点的compatible属性来判断是否支持该设备。
- reg:指定设备的寄存器地址和大小。该属性通常包含一个或多个地址范围和对应的大小,用于描述设备寄存器的配置。
- interrupt-parent和interrupts:指定设备的中断信息。interrupt-parent属性指定中断控制器的设备树节点路径,interrupts属性指定中断号或中断描述符。
- clocks:指定设备的时钟源。该属性通常包含一个或多个时钟源的设备树节点路径,用于描述设备所需的时钟信号。
- interrupts-extended:扩展的中断属性,用于描述复杂的中断控制器和中断路由。
- pinctrl-0:指定设备的引脚控制器配置。该属性通常包含一个引脚控制器的设备树节点路径,用于描述设备的引脚配置。
比如:
{
model = "UISRC.COM MZU784";
compatible = "uisrc,mzu784-2CG",
"xlnx,zynqmp-zcu100-revC",
"xlnx,zynqmp-zcu100",
"xlnx,zynqmp";
aliases {
ethernet0 = &gem3;
rtc0 = &rtc;
i2c0 = &i2c0;
serial0 = &uart0;
serial1 = &uart1;
spi0 = &qspi;
usb0 = &usb0;
mmc0 = &sdhci0;
mmc1 = &sdhci1;
};
chosen {
bootargs = "earlycon clk_ignore_unused";
stdout-path = "serial0:115200n8";
};
memory@0 {
device_type = "memory";
reg = <0x0 0x0 0x0 0x3ff00000>;
};
cpus {
/delete-node/ cpu@2 ;
/delete-node/ cpu@3 ;
};
};
具体参数请参考设备用户手册
8 内核对设备树处理前提
在进行设备树处理之前,需要满足以下前提条件:
- 硬件支持:设备树是对硬件的描述,因此需要确保使用的硬件支持设备树。
- 编译器支持:设备树通常是以源码的形式编写的,因此需要确保使用的编译器支持设备树文件的编译和生成。
- 内核支持:设备树需要在内核中进行处理和解析,因此需要确保使用的内核版本支持设备树。
- 设备树工具:设备树处理过程中,需要使用一些设备树工具来生成、修改和编译设备树文件,需要确保这些工具已经安装并配置正确。
- 设备树文件:需要有正确的设备树文件,以描述硬件的信息和配置。这些设备树文件通常由硬件厂商提供,并需要根据具体的硬件进行修改和定制。
- 引导程序支持:在启动过程中,需要有引导程序(如 U-Boot)支持设备树的加载和传递给内核。