转自:https://www.cnblogs.com/Mike2019/p/12191769.html
将描述板级硬件信息的内容从Linux分离出来,用一个专属的文件来描述,这个专属文件叫做设备树,文件扩展名.dts。而一个SOC可以做出很多不同的板子,这些板子都有共同的信息,将这些共同的信息提取出来作为一个通用的文件,其他.dts文件直接引用这个通用文件即可,这个通用文件就是.dtsi文件。
1、存放路径
使用设备树之前ARM架构的板级信息存放在:
/arch/arm/mach-xxx
/arch/arm/plat-xxx
使用设备树之后ARM架构的板级信息存放在:
/arch/arm/boot/dts
dts工具源码存放在:
scripts/dtc/Makefile
2、DTS语法
2.1. 文件引用
像c语言那样可以使用#include引用.dtsi、.dts、.h文件。
#include <dt-bindings/input/input.h>
#include “imx6ull.dtsi”
#include “imx6ull-14x14-evk.dts”
2.2. 文件布局
/dts-v1/; #dts文件的版本号
[memory reservations] #可以不写,表示内核使用全部的内存;使用,表示留下一部分内存给自己使用
/{ #根节点
[property]
[child nodes]
[child nodes]
......
};
2.3. nodes节点格式
[label:] node-name [@unit-address]{
[property]
[child nodes]
[child nodes]
......
};
[]:表示该项可以省略
[label]:标签,为了方便访问节点,后面可以直接通过&label来访问该节点。
node-name:节点名称。
[@unit-address]:通常表示设备的地址或寄存器首地址,为了多增加一个信息区分同一个node-name(同一级别下)。
cpu0: cpu@0 {
compatible = "arm,cortex-a7";
device_type = "cpu";
reg = <0>;
......
};
cpu1: cpu@1 {
compatible = "arm,cortex-a8";
device_type = "cpu";
......
};
2.4. property属性格式
[label:] prooerty-name = value; //有值
[label:]property-name; //没有值
2.4.1 value:属性的键值
a.字符串
compatible = “arm,cortex-a7”;
b.32位无符号整数
reg = <1 0x123456 100>
c.16尽职字节序列
reg = [00 11 22 33] //每个数据必须是2位
d.字符串列表
compatible = “fsl,imx6ull-gpmi-nand”, “fsl,imx6ul-gpmi-nand”;
2.4.2 标准属性
1.compatible
兼容性属性,用于将设备和驱动绑定起来。格式如下:
compatible = "manufacturer, model" //manufacturer:厂商, model:模块对应的驱动名字
例如某开发板音频设备节点的compatible属性:
compatible = "fsl, imx6ul-evk-wm8960", "fsl, imx-audio-wm8960"
这个设备首先使用第一个compatible值在内核查找与之匹配的驱动文件,如果找不到就使用第二个人compatible值。
2.model
描述设备模块信息,比如名字、详细版本号。用于区分compatible相同时。
model = "wm8960-audio-V1.0"
3.status
描述设备状态信息
4. reg
#address-cells = <1> //表示reg里面的数据address占用一个字长
#size-cells = <1> //表示reg里面的数据size占用一个字长
gpio-spi: gpio_spi@0{
compatible = ".spi"
reg = <address1 length1 address2 length2 ......> //address一般用来表示寄存器起始地址,length一般表示寄存器长度
}
2.4.3 根节点compatible属性
每个节点都有compatible属性,根节点“/”也不例外。
设备节点的compatible属性:是为了匹配Linux内核中的驱动程序。
根节点的compatible属性:是为了确认Linux内核是否支持次设备,一般,第一个值描述所使用的硬件设备名字,比如:imx6ull-14x14-evk
;第二个值描述设备所使用的SOC,比如imx6ull。
/ {
model = "Freescale i.MX6 ULL 14x14 EVK Board";
compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
......
}
2.5 向节点追加或修改内容
由于.dtsi文件是设备树的头文件,其他所有使用相同SOC的板子都会使用,因此我们可以在.dts文件#include相关.dtsi文件,然后在.dts文件追加或者修改内容。
例如:
imx6ull.dtsi文件:
LED:gpio_ led{
compatible = "imx6ull_led"
pin = <imx6ull_GPA(0)>
}
在imx6ull_evk.dts文件往gpio_led追加内容:
#include "imx6ull.dtsi"
&LED{ //使用&访问之前定义的的节点
pin = <imx6ull_GPA(1)> //修改内容
reg = <......> //追加内容
}
/{ //根节点
......
}
3 使用设备树以后,设备匹配方法
在arch/arm/mach-imx/mach-imx6ul.c 文件
代码中设置.dt_compat = imx6ul_dt_compat,imx6ul_dt_compat表里面有"fsl,imx6ul"和“fsl,imx6ull”两个兼容值。只要某个设备(板子)根节点“/”的compatible属性值与imx6ul_dt_compat表中的任何一个值相等,那么就表示Linux内核支持此设备。