设备树简介

2019-07-12 20:04发布

一 arm-linux内核设备树来源

在过去的arm-linux内核源码树中arch/arm/plat-xxx和arch/arm/mach-xxx 等目录下充斥着大量的垃圾代码,相当多数的代码只是在描述板级细节信息,而这些板级细节信息对于内核来说都是垃圾代码,比如板上的 platform_device、 resource、 i2c_board_info、 spi_board_info 以及各种硬件的 platform_data。 为了改变这种局面,ARM 社区开始使用 PowerPC 等其他体系架构下已经使用的Flattened Device Tree(FDT)。Device Tree 是一种描述硬件的数据结构,它起源于OpenFirmware(OF)。采用 Device Tree后,许多板级细节信息可以直接通过Device Tree传递给 linux内核,而不需要在arch/arm/plat-xxx和arch/arm/mach-xxx中进行大量的冗余编码,内核启动时会展开Device Tree并创建和注册相关的设备(比如platform_device,i2c_client,spi_device),同时驱动程序也会以新的方式和Devie Tree中定义的设备结点进行匹配。Device Tree的主要优势:对于使用相同主芯片的不同板卡,只需更换设备树文件dtb即可实现不同板卡的无差异支持。

二 arm-linux内核设备树简介

Device Tree由一系列被命名的结点(node)和属性(property)组成,而结点本身可包含子结点,所谓属性就是成对出现的name和value。 在Device Tree中可描述的信息包括: system runtime parameter,比如:bootargs cpu数量和类别 memory基地址和大小 总线控制器和桥 总线外设 内核基础设施及其使用情况,比如: 中断控制器和中断使用情况 DMA控制器和DMA使用情况 GPIO控制器和GPIO使用情况 CLOCK控制器和ClOCK使用情况 PINCTRL控制器和PINCTRL使用情况 从上述信息可知Device Tree并不能描述所有硬件信息,一般可以动态识别的设备,比如USB设备,PCI/PCIe设备是不需要进行描述的,它们在设备热插拔时,由内核进行探测 设备树包含DTC(device tree compiler)、 DTS(device tree source) 和 DTB(device tree binary),其对应关系如下图1所示: 图1 下面简单描述 dts文件,dtb文件和DTC dts文件是一种ASCII文本文件,放置在arch/arm/boot/dts目录。由于每个主芯片可能存在多个电路板,每个电路板都有一个 dts文件,这些 dts文件势必会存在很多公用代码,linux 内核为了简化,把主芯片公用的部分或者多个machine 公用的部分保存到 dtsi文件,供不同的dts文件引用。例如vexpress-v2a.dts引用了vexpress-v2.dtsi,此时vexpress-v2a.dts中会有如下行:#include “vexpress-v2.dtsi”,告诉编译器vexpress-v2a.dts需要引用vexpress-v2.dtsi,类似于C语言的头文件,dtsi 也可以 include 其他的dtsi,例如几乎所有ARM芯片的dtsi 文件都引用了 skeleton.dtsi DTC为编译工具,源码位于scripts/dtc目录,它可以将dts文件编译成dtb文件,下面为dts文件的Makefile: dtb-$(CONFIG_ARCH_VEXPRESS) += vexpress-v2a.dtb vexpress-v2b.dtb vexpress-v2c.dtb vexpress-v2d.dtb 从上述Makefile可知,若选择CONFIG_ARCH_VEXPRESS, vexpress-v2a.dts、vexpress-v2b.dts、vexpress-v2c.dts、vexpress-v2d.dts 都会被编译成相应的dtb文件,bootloader在引导内核时,会预先读取dtb文件到内存,等待内核启动时进行解析

三 arm-linux内核设备树语法

下面以最简单的machine 进行讲解,假设此 machine 的配置如下: 双核ARM Cortex-A9处理器 2 个串口(分别位于0x101F1000和0x101F2000) GPIO 控制器(位于0x101F3000) SPI 控制器(位于0x101F4000) I2C 控制器(位于0x101F5000) I2C 控制器连接了maxim ds1338 实时钟(i2c地址为0x58) 中断控制器(位于0x10100000)