一、概念
1、什么是设备树?
设备树(Device Tree),就是具有树形结构的设备统一管理。描述设备树的文件叫做DTS(Device Tree Source)这个DTS文件采用树形结构描述板级设备,也就是开发板上的设备信息。例如:
树的主干就是系统总线, IIC 控制器、 GPIO 控制器、 SPI 控制器等都是接到系统主线上的分支。IIC 控制器有分为 IIC1 和 IIC2 两种,其中 IIC1 上接了 FT5206 和 AT24C02这两个 IIC 设备, IIC2 上只接了 MPU6050 这个设备。
2、设备树的由来
DTS 文件的主要功能就是按照上图所示的结构来描述板子上的设备信息, DTS 文件描述设备信息是有相应的语法规则要求的,在3.x版本以前的Linux内核中ARM架构并没有采用设备树。以前要描述ARM架构的板级信息是在Linux内核源码中arch/arm/mach-xxx 和 arch/arm/plat-xxx 文件夹创建一个.c的文件存放板级的信息。
但是一个芯片能制作成很多的板子,比如我们所知道的st公司的F4系列的芯片就拓展了很多的板子。一个板子对应一个.c文件。导致Linux内核下的板级信息非常多,导致Linux内核冗余。Linux之父linus就发火了,从此之后ARM社区就引入了设备树来描述板级信息,将这些内容从Linux内核中分离开,用一个专属的文件格式来描述:设备树(文件扩展名.dts)。
一个SOC能制作出很多不同的板子,但是不同的板子肯定也有共同的信息,将这些共同的信息提取出来作为一个通用的文件,其他的设备树(.dts)文件直接引用这个通用的文件即可,这个通用的文件就是.dtsi文件,类似于C语言中的头文件。
二、DTS、DTB和DTC
1、概念
DTS:设备树的源码文件。
DTB:DTS编译后得到的二进制文件。
DTC:DTS要编译从DTB所使用到的编辑器。
可以类比于C语言,.c文件相当于设备树的源文件(DTS),DTB文件相当于.c文件编译链接后的二进制文件,而.c文件编译链接需要编辑器,比如gcc编辑器。DTC就相当于gcc编辑器。
注:如果只编辑设备树的话建议使用命令:make dtsb
2、DTS语法
DTS语法就是用来编写.dts的规定,比如C语言的编写规定一样。DTS语法非常人性化,是一种ASCII文本文件,不管是阅读还是修改都挺方便。参考《Power_ePAPR_APPROVED_v1.12》
①、.dtsi头文件
我们打开前面我们移植的NXP官方的Linux内核的源码,找到我们添加的阿尔法开发板的.dts文件:
.dtsi头文件和C语言中的.h文件一样,可以使用#include来包含,不仅可以应用.dtsi文件,还可以引用.dts文件。
一般.dtsi文件描述的是SOC外部的信息,比如:CPU架构、主频、外设寄存器地址范围,中断等等,而.dts文件就具体到一个外设下的具体的设备或者传感器。
②、设备节点
设备树采用属性结构来描述板子上的设备信息的文件,每个设备都是一个节点,每个节点都通过属性信息来描述结点信息,比如说我们前面移植添加的imx6ull-alientek-emmc.dts文件中:
backlight节点,它描述LCD背光的信息, 它的前面还有"/"表示根节点。compatible、pwms灯就是backlight节点的属性信息,来描述这个节点的信息。
在imx6ull-alientek-emmc.dts中引用头文件imx6ull.dtsi,在imx6ull.dtsi中也有根节点"/",那么这两个根节点设备树同一个呢?会不会有冲突呢?,其实这两个节点都是同一个节点,最终这个"/"根节点会合并成一个,里面的属性信息也会合并。
设备树节点命名:
node-name@unit-address
节点名字的格式:node-name@unit-address,"node-name"是节点名字,是ASCII字符串,能够清晰描述设备的功能。"unit-address"一般表示设备的地址或者寄存器首地址,如果某个节点没有地址或者寄存器,"unit-address"可以不要。如:cpu@0、和interruptcontroller@00a01000。
其中,有一些节点如图:
这就是另一种节点的命名方式,":"前面表示节点标签(label)":"后面才是节点名字。
label: node-name@unit-address
引入 label 的目的就是为了方便访问节点,可以直接通过&label 来访问这个节点,比如通过
&cpu0 就可以访问“cpu@0”这个节点,而不需要输入完整的节点名字。
③、标准属性
属性用来描述节点信息,每个节点都有不同的属性,用户可以自定义属性,除了用户自己定义的属性,有很多的标准属性。
1、compatible属性
compatible属性也叫兼容性属性,非常重要!,compatible属性的值是一个字符串列表,compatible 属性用于将设备和驱动绑定起来。字符串列表用于选择设备所要使用的驱动程序, compatible 属性的值格式如下所示:
"manufacturer,model"
manufacturer:表示厂商。
model:表示模块对应驱动的名字。
根节点的compatible属性可以知道我们所使用的设备,一般第一个值描述了所使用的硬件设备名字。第二个值描述了设备所使用的 SOC。Linux 内核会通过根节点的 compoatible 属性查看是否支持此设备,如果支持的话设备就会启动 Linux 内核。否者不启动。
比如:
sound节点 表示开发板的音频设备节点,fsl表示厂商为飞思卡尔,imx6ul-evk-wm8960和imx-audio-wm8960表示驱动模块的名字。sound这个设备首先使用第一个兼容值在 Linux 内核里面查找,看看能不能找到与之匹配的驱动文件,如