设备树的格式和属性


Devicetree 格式

1. DTS 文件的格式

DTS 文件布局(layout):

/dts-v1/;                          //表示版本
[memory reservations]              //格式为:/memreserve/ <address> <length>
/{
	[property definitions]
	[child nodes]
};

2. node 的格式

设备树中的基本单元,被称为“node”,其格式为:

[label:] node-name[@unit-address]{
	[properties definitions]
	[childe nodes]
}

label 是标号,可以省略。label 的作用是为了方便地引用 node,比如:

/dts-v1/;
/ {
	uart0: uart@fe001000 {
		compatible="ns16550";
		reg=<0xfe001000 0x100>;	
	};
};

可以使用下面的 2 种方法来修改 uart@fe001000 这个 node:

//在根节点之外使用label引用node:
&uart0 {
	status = "disabled";
};
//或在根节点之外使用全路径:
&{/uart@fe001000}{
	status = "disabled";
};

3. properties 的格式

简单地说,properties 就是“name=value”,value 有多种取值方式。

  • Property 格式 1:
[label:] property-name = value;
  • Property 格式 2(没有值):
[label:] property-name;
  • Property 取值只有 3 种:
arrays of cells(1个或多个32为数据,64位数据使用2个32位数据表示),
string(字符串),
bytestring(1个或多个字节)

示例:

  1. Arrays of cells:cell 就是一个 32 为数据,用尖括号包围起来
interrupts = <17 0xc>;

64bit 数据使用 2 个 cell 来表示,用尖括号包围起来:

clock-frequency = <0x00000001 0x00000000>;
  1. A null-terminated string (有结束符的字符串),用双引号包围起来:
compatible = "sigple-bus";
  1. A bytestring (字节序列),用中括号包围起来:
local-mac-address = [00 00 12 34 56 78];     //每个byte用2个16进制数来表示
local-mac-address = [000012345678];          //每个byte用2个16进制数来表示
  • 可以是各种值的组合,用逗号隔开
compatible = "ns16550","ns82555";
example = <0xf00f000 19>,"a strange property format";

dts 文件包含 dtsi 文件

设备树文件不需要我们从 0 写出来,内核支持了某款芯片比如 imx6ull,在内核的 arch/arm/boot/dts 目录下就有了能用的设备树模板,一般命名为 xxxx. dtsi。“i”表示“include”,被别的文件引用的。

我们使用某款芯片制作出了自己的单板,所用资源跟xxxx. dtsi 是大部分相同,小部分不同,所以需要引脚 x xxx. dtsi 并修改。dtsi文件跟 dts 文件的语法是完全一样的。

dts中可以包含 h 头文件,也可以包含 dtsi 文件,在 .h 头文件中可以定义
一些宏。示例:

/dts-v1/;
#include <dt-bindings/input/input.h>
#include "imx6ull.dtsi"

/{
......
};

常用的属性

1. #address -cells、#size-cells

  • cell 值一个 32 为的数值;
  • address-cells:address 要用多少个 32 位数来表示;
  • size-cells:size 要用多少个 32 位数来表示。
    比如一段内存,怎么描述它的起始地址和大小?
/ {
#address-cells = <1>;
#size-cells = <1>;
memory {
reg = <0x80000000 0x20000000>;
	};
};

上述例子中,address-cells 位为 1,所以 reg 中用 1 个数来表示地址,即用 0x80000000 来表示地址;size-cells 为 1,所以 reg 中用 1 个数来表示大小,即用 0x20000000 表示大小。

2. compatible

“compatible”表示“兼容”,对于某个 LED,内核中可能有 A、B、C 三个驱动都支持它,那么可以这么写:

led {
compatible = "A","B","C";
};

内核启动时,就会为这个 LED 按这样的优先顺序为它找到驱动程序:A,B,C。

根节点也有 compatible 属性,用来选择哪一个“machine desc”:一个内核可以支持 machine A,也支持 machine B,内核启动后会根据根节点的 compatible 属性找到对应的 machine desc(机器描述) 结构体,执行其中的初始化函数。

compatible 的值,建议这样取:“manufacturer,model”,即“厂家名,模块名”。

3. model

model 属性与 compatible 属性有点类似,但是有差别。

compatible 属性是一个字符串列表,表示可以你的硬件兼容 A、B、C 等驱动;

model 用于准确地定义这个硬件是什么。
比如根节点可以这样写:

{
	compatible = "sansung,smdk2440","samsung,mini2440";
	model = "jz2440_v3";
};

它表示这个单板,可以兼容内核中的“smdk2440”,也兼容“mini2440”。

从 compatible 属性可以知道兼容哪些板子,但是它到底是什么板?用 model 属性来明确。

4. status

dtsi 文件中定义了很多设备,但是在你的板子上某些设备是没有的。这是可以给这个设备节点添加一个 status 属性,设置为“disabled”:

&uart1 {
	status = "disabled";
};

![[8-1 设备属性.png]]

5. reg

reg 的本意是 register,用来表示寄存器地址。

但是在设备数里,它可以用来描述一段空间。反正对于 ARM 系统,寄存器和内存是统一编址的,即访问寄存器时用某块地址,访问内存时用某块地址,在访问方法上没有区别。

reg 属性的值,是一系列的“address size”,用多少个 32 位的数来表示 address 和 size,由其父节点的#address-cells、#size-cells 决定。
示例:

/dts-v1/;
/ {
#address-cells = <1>;
#size-cells = <1>;
memory {
reg = <0x80000000 0x20000000>;
};
};

6. name(过时了,建议不用)

它的值是字符串,用来表示节点的名字。在跟 platform_driver 匹配时,优先级最低。
compatible 属性在匹配过程中,优先级最高。

7. device_type(过时了,建议不用)

它的值是字符串,用来表示节点的类型。在跟 platform_driver 匹配时,优先级为中。
compatible 属性在匹配过程中,优先级最高。


常用的节点(node)

1. 根节点

dts 文件中必须有一个根节点:

/dts-v1/;
/ {
model = "SMDK2440";
compatibel = "samsung,smdk2440";

#address-cells = <1>;
#size-cells = <1>;
};

根节点中必须有这些属性:

#address-cells              // 在它的子节点的reg属性中,使用多少个u32整数来描述地址(address)
#size-cells                 // 在它的直接点的reg属性中,使用多少给u32整数来描述大小(size)
compatible                  // 定义一系列的字符串,用来指定内核中哪个machine_desc可以支持本                               // 即这个板子兼容哪些平台
                            // uImage : smdk2410 smdk2440 mini2440     ==> machine_desc

model                       // 这个板子是什么
                            // 比如有2款板子配置基本一致,它们的compatible是一样的
                            // 那么就通过model来分辨这2款板子

2. CPU 节点

一般不需要我们设置,在 dtsi 文件中都定义好了:

cpu {
	#address-cells = <1>;
	#size-cells = <0>;

	cpuo: cpu@0 {
		......
	};
};

3. memory 节点

芯片厂家不可能事先确定你的板子用了多大的内存,所以 memory 节点需要板厂设置,比如:

memory {
reg = <0x80000000 0x20000000>;
};

4. chosen 节点

我们可以通过设备树文件给内核传入一些参数,这要在 chosen 节点中设置 bootargs 属性:

chosen {
bootargs = "noinitrd root=/dev/mtdblock4 rw init=/linuxrc console=ttySAC0,115200";
};
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值