(1) 语法:
Devicetree node格式:
[label:] node-name[@unit-address] {
[properties definitions](属性定义)
[child nodes](子节点)
};
label: 用于其他节点引用该节点
node-name:节点名
unit-address:由于同一级别下的子节点名称不能相同,可以使用unit-address对名字进行修饰来区分两个类似的节点。
Property格式1:
[label:] property-name = value;
Property格式2(没有值):
[label:] property-name;
Property取值只有3种:
<>修饰的内容为arrays of cells(1个或多个32位数据, 64位数据使用2个32位数据表示,)
""修饰的内容为string(字符串 )
[]修饰的内容为bytestring(16进制表示1个或多个字节,一个byte用2位16进制数来表示,不可省略数字,byte之间的空格可省略)
示例:
a. Arrays of cells : cell就是一个32位的数据
interrupts = <17 0xc>;
b. 64bit数据使用2个cell来表示: 高字节在前
clock-frequency = <0x00000001 0x00000000>;
c. A null-terminated string (有结束符的字符串):
compatible = "simple-bus";
d. A bytestring(字节序列) :
local-mac-address = [00 00 12 34 56 78]; // 每个byte使用2个16进制数来表示
local-mac-address = [000012345678]; // 每个byte使用2个16进制数来表示
e. 可以是各种值的组合, 用逗号隔开:
compatible = "ns16550", "ns8250";
example = <0xf00f0000 19>, "a strange property format";
(2) DTS文件布局(layout):
/dts-v1/;
[memory reservations]
// 格式为: /memreserve/ <address> <length>;
//保留从address开始的长度为length的内存不让内核访问
/ {
[property definitions]
[child nodes]
};
(3) 特殊的、默认的属性:
a. 根节点:
#address-cells: 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)
#size-cells:在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size)
compatible:定义一系列的字符串, 用来指定内核中哪个machine_desc可以支持本设备,即这个板子兼容哪些平台。
假设编译好的uImage支持smdk2410 smdk2440 mini2440等单板,我们就可以通过compatible制定使用哪个单板。
model:具体是哪一个板子,比如有2款板子配置基本一致, 它们的compatible是一样的,那么就通过model来分辨这2款板子
例如:
model = "SMDK24440"; //板子的具体型号
compatible = "samsung,smdk2440"; //支持三星公司的smdk2440
#address-cells = <1>;
#size-cells = <1>;
b. /memory
device_type = "memory";
reg // 用来指定内存的地址、大小
例如:
memory {
device_type = "memory";
reg = <0x30000000 0x4000000 0 0x4096>;
};
第一块内存起始地址0x30000000 大小0x4000000
第二块内存起始地址0 大小4096
c. /chosen
bootargs // 内核command line参数, 跟u-boot中设置的bootargs作用一样
例如:
chosen {
bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200";
};
d. /cpus
/cpus节点下有1个或多个cpu子节点, cpu子节点中用reg属性用来标明自己是哪一个cpu
所以 /cpus 中有以下2个属性:
#address-cells // 在它的子节点的reg属性中, 使用多少个u32整数来描述地址(address)
#size-cells // 在它的子节点的reg属性中, 使用多少个u32整数来描述大小(size)
e. /cpus/cpu*
device_type = "cpu";
reg // 表明自己是哪一个cpu
(4) 引用其他节点:
a. phandle : // 节点中的phandle属性, 它的取值必须是唯一的(不要跟其他的phandle值一样)
pic@10000000 {
phandle = <1>;
interrupt-controller;
};
another-device-node {
interrupt-parent = <1>; //interrupt-parent引用phandle为1的节点
// 使用phandle值为1来引用上述节点
};
b. label:
PIC: pic@10000000 {
interrupt-controller;
};
another-device-node {
interrupt-parent = <&PIC>; // 使用label来引用上述节点,
// 使用lable时实际上也是使用phandle来引用,
// 在编译dts文件为dtb文件时, 编译器dtc会在dtb中插入phandle属性
};
(5)特殊用法简介
dts文件可包含dtsi文件,dts中如果重复定义了dtsi中的节点会覆盖dtsi中的值。
例如有一个dtsi文件如下,文件名为jz2440.dtsi
// SPDX-License-Identifier: GPL-2.0
/*
* SAMSUNG SMDK2440 board device tree source
*
* Copyright (c) 2018 weidongshan@qq.com
* dtc -I dtb -O dts -o jz2440.dts jz2440.dtb
*/
#define S3C2410_GPA(_nr) ((0<<16) + (_nr))
#define S3C2410_GPB(_nr) ((1<<16) + (_nr))
#define S3C2410_GPC(_nr) ((2<<16) + (_nr))
#define S3C2410_GPD(_nr) ((3<<16) + (_nr))
#define S3C2410_GPE(_nr) ((4<<16) + (_nr))
#define S3C2410_GPF(_nr) ((5<<16) + (_nr))
#define S3C2410_GPG(_nr) ((6<<16) + (_nr))
#define S3C2410_GPH(_nr) ((7<<16) + (_nr))
#define S3C2410_GPJ(_nr) ((8<<16) + (_nr))
#define S3C2410_GPK(_nr) ((9<<16) + (_nr))
#define S3C2410_GPL(_nr) ((10<<16) + (_nr))
#define S3C2410_GPM(_nr) ((11<<16) + (_nr))
/dts-v1/;
/ {
model = "SMDK24440";
compatible = "samsung,smdk2440";
#address-cells = <1>;
#size-cells = <1>;
memory { /* /memory */
device_type = "memory";
reg = <0x30000000 0x4000000 0 4096>;
};
/*
cpus {
cpu {
compatible = "arm,arm926ej-s";
};
};
*/
chosen {
bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200";
};
led {
compatible = "jz2440_led";
pin = <S3C2410_GPF(5)>;
};
};
1)使用phandle
/dts-v1/;
#include "jz2440.dtsi" //包含dtsi文件
/{
led{
pin = <S3C2410_GPF(6)> ; //重定义led节点中的pin值
};
}
编译之后pin最终会等于S3C2410_GPF(6)。
2)使用label
增加dtsi led节点的label为LED
LED:led {
compatible = "jz2440_led";
pin = <S3C2410_GPF(5)>;
};
在dts文件引用LED,然后修改pin的值
/dts-v1/;
#include "jz2440.dtsi"
&LED{
pin = <S3C2410_GPF(6)> ;
}
效果和第一个相同。
官方文档:
https://www.devicetree.org/specifications/