一、诞生背景
硬件设备中种类逐年递增,板级platform平台设备文件越来越多
二、设备树简介
如下图, 设备树由 根节点 开始,可以包含若干个 子节点 ; 每个 子节点 又可以包含若干个 子节点 …
- DTS(device tree source):设备树源文件,ASCII 格式
- DTC(device tree compiler):设备树编译工具。将
dts文件 编译成 dtb文件 - DTB(device tree blob):二进制设备树
1、设备树使用
uboot负责加载 dtb文件 到内存的 特定位置 ,内核在启动时从这个位置获取 dtb文件 并解析使用
设备树源文件 dts
ascii格式 arch/arm/boot/dts/imx6ull-alientek-emmc.dts
二进制设备树
二进制格式 arch/arm/boot/dts/imx6ull-alientek-emmc.dtb
将编译得到的 dtb 文件放到 tftp目录下, uboot 会从此目录下获取 dtb 文件 ,并放到内核的指定位置,等待内核启动时解析。
设备树编译工具 dtc
dtc也是由源码变异而得到的应用程序。
可以借助内核Makefile 的 dtbs目标来编译设备树,也可以手动调用工具dtc来编译设备树。
1、内核伪目标编译设备树
编译dts
make ARCH=arm -j4 CROSS_COMPILE=arm-linux-gnueabihf- dtbs
2、手动编译设备树
编译 dts 为 dtb
./scripts/dtc/dtc -I dts -O dtb -o xxx.dtb arch/arm/boot/dts/xxx.dts
反编译 dtb 为 dts
./scripts/dtc/dtc -I dtb -O dts -o xxx.dts arch/arm/boot/dts/xxx.dtb
-I :指定输入格式,为dts -O :指定输出格式,为dtb -o :指定输出文件
2、设备树框架
-
从上到下
- 头文件
- 主体
- 子节点追加内容(注意追加节点不要放在根节点范围里)
-
从外到内
头文件:
#include <dt-bindings/input/input.h>
#include "imx6ull.dtsi"
主体:
注意 *,dtsi 文件中也有 / 根节点。经过内核解析后会和 主体的根节点 合并。
/ {
model = "Seeed i.MX6 ULL NPi Board";
compatible = "fsl,imx6ull-14x14-evk", "fsl,imx6ull";
aliases {
pwm0 = &pwm1;
pwm1 = &pwm2;
pwm2 = &pwm3;
pwm3 = &pwm4;
};
chosen {
stdout-path = &uart1;
};
memory {
reg = <0x80000000 0x20000000>;
};
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
linux,cma {
compatible = "shared-dma-pool";
reusable;
size = <0x14000000>;
linux,cma-default;
};
};
...
};
子节点追加内容
若要对某个节点A追加内容,只需增设 &A 节点即可,&A 节点内容就是要追加的内容。 A 是节点标签 而且 追加节点 要放在 根节点的外面。
&cpu0 {
dc-supply = <®_gpio_dvfs>;
clock-frequency = <800000000>;
};
&clks {
assigned-clocks = <&clks IMX6UL_CLK_PLL4_AUDIO_DIV>;
assigned-clock-rates = <786432000>;
};
&fec1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet1>;
phy-mode = "rmii";
phy-handle = <ðphy0>;
status = "okay";
};
3、节点命令
基本方法
node-name@unit-address{
属性1 = …
属性2 = …
属性3= …
子节点…
}
- node-name:指定节点的名称
- “unit-address”用于指定“单元地址”
节点标签
cpu0: cpu@0 {
compatible = "arm,cortex-a7";
device_type = "cpu";
reg = <0>;
}
在追加节点、引用节点时,都要使用该节点的标签。
别名子节点
与上面标签的不同是:别名子节点可以批量地为若干个节点规定别名。
aliases {
can0 = &flexcan1;
can1 = &flexcan2;
ethernet0 = &fec1;
ethernet1 = &fec2;
...
}
|