设备树概述
在linux2.6以前,arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量重复的、用于描述设备细节的代码。导致内核代码迅速膨胀,linus一声怒吼“This whole ARM thing is a f*cking pain in the ass”,自此ARM开发便开始了使用设备树描述设备细节的时代。
名词解释:
FDT : Flattened Device Tree 展开设备树
OF : Open Firmware 开放固件
DTC : Device Tree Compiler 设备树编译器
DTS :Device Tree Source 设备树源文件,类似于.c文件
DTSI :Device Tree Source Include 设备树源包含文件,类似于.h文件,将一些通用的设备树结构放置在此文件中,以供其它dtb文件include
DTB : Device Tree Bin 设备树二进制文件,类似于编译后的可执行文件
设备树的特点
- 设备树可以描述的信息:CPU的数量和类别、总线、外设连接、中断控制器与使用情况使用、GPIO控制器与使用情况、clock控制器与使用等。
- 设备树被保存在一个ASCII文本文件中,类似于xml文件;在arm linux中,一个.dts文件对应一个ARM的machine放置在arch/arm/boot/dts目录。
- 设备树是一种数据结构,用于描述设备信息的语言。device tree由一系列被命名的节点(node)和属性(property)组成,节点可包含子节点。属性由name和value组成。
- 设备树源文件dts被编译成dtb二进制文件,由bootload运行时传递给内核,由内核进行解析为硬件拓扑图,在编程时调用系统提供的接口获取到设备树中的节点和属性信息。
如下图所示,imx6q的设备树源文件
设备树的使用
编译与加载
- 设备树文件放置在
/arch/arm/boot/dts
中,该文件夹有一个Makefile,其中定义了设备树的编译条件。如下图所示:
- 根据编译内核时不同的.config定义来编译指定的设备树文件,如
/arch/arm/configs/s3c6400_deconfig
中的设备树编译定义:
- 使用
make dtbs
命令编译 - 拷贝编译好的dtb文件到boot加载目录
~/tftpboot
- 设置启动参数,
set bootcmd tftp 0x410000000 uImage\; tftp 0x420000000 xxx.dtb\; bootm 0x41000000 - 0x42000000
。可在uboot中使用pri
打印环境信息看到。
DTS语法
节点与子节点
以s3c4200的dts为例:
- 节点名称:每个节点必须有一个“<名称>[@<设备地址>]”形式的名字,且同级节点名称唯一。
<名称>是不超过31位的字符串,节点名应体现其对应的设备类型
<设备地址>用来访问该设备的主地址,并且该地址也在reg属性中列出。设备地址为可选项,主要用来区分同名设备。 - 每个表示一个设备的节点需要有compatible属性。
属性
键值对,可以为空或者任意字节。有以下5种基本的数据表示形式:
- 字符串:用双引号包含,如:device = “memory”
- 无符号整数:用<>包含,如:size = <1024>
- 二进制数据:用[ ] 包含,如:binary_property = [01 23 45]
- 数据连接:用,连接:如 : “string”,<123>,“end”
常见属性:
-
compatible属性
指定了系统的名称,包含“<制造商>,<型号>”形式的字符串,重要的是指定一个确定的设备,以避免命名空间冲突。
-
reg属性
reg的组织形式为reg = <address1 length1 [address2 length 2]…>,其中每一组(address length)表明设备使用的一个地址范围。
-
#address-cells和#size-cells
对子节点的reg属性进行限定。
#address-cells = <1>表示address字段长度为1;
#size-cells = <1>表示length字段长度为1; -
中断属性
设备树的编程接口和方法
##常用OF API
#include <linux/of.h> ///< OF接口API