设备树:
本质是一个文件,包含很多节点,每个节点里边是对设备属性的描述(包括GPIO,时钟,中断等等),其中节点(node)和属性(property)就是设备树最重要的两个概念。
路径一般在arch/arm/boot/dts、
工作流程:设备树dts文件被编译成dtb二进制文件,在boot loader运行时传递给操作系统。
为什么要整个设备树的概念?
传统的平台总线设备通过platform_device这一个结构体来描述,每个platform_device描述一个特定的外设,通过注册到平台总线上以保证内核和设备之间能通讯。然而,随着时间推移,外设越来越多,导致LinuxARM部分的设备配置代码杂乱重复,造成工作和维护难度加大。
于是设备树孕育而生,它提供了一种统一的硬件描述方式,相较之前的
platform_device更加灵活,轻便。
关键术语解读:
DTS、DTSI、DTB 和 DTC
DTS:设备树源文件,可由我们直接编写,包含设备的结构,属性和连接关系。
DTSI:包含在DTS文件下,主要是用于定义一些可重用的部分,可以被多个DTS文件共享,提高可重用性。
DTB:DTS和DTSI文件编译得到的二进制文件。可被操作系统解析,在系统运行过程被灵活调用。
DTC:设备树的编译器,把DTS和DTSI文件编译成DTB文件的工具。
设备树编译
dtc -I dts -O dtb -o output.dtb input.dts
其中,
`input.dts`
是输入的设备树源文件,
`output.dtb`
是编译后的二进制设备树文件。
编译前确保在scripts/dtc/路径下有dtc编译器
如果没有生成相应的
dtc
可执行文件, 可以查看在内核默认配置文件中 CONFIG_DTC
是否使能
设备树反编译
dtc -I dtb -O dts -o output.dts input.dtb
input.dtb
是输入的二进制设备树文件,
output.dts
是反编译后的设备树源文件。
设备树基本语法
1-根节点((Root Node)
整个设备的起点一般以/开始,后面加花括号
2-子节点
根字节的子项,用于表示具体设备,以下时子节点的数据格式。
(
1
)节点标签(
Label)(可选):用于在设备树中引用该节点,其他节点也可引用。
(
2
)节点名称(
Node Name
):字符串,通常是设备的名字,唯一!
(
3
)单元地址(
Unit Address)(可选):是区分相同类型的设备的不同实例
(
4
)属性定义(Properties Definitions):是一组键值对,用于描述设备的配置和特性,
例如寄存器地址、中断号、时钟频率等
(5) 子节点(Child Nodes):是当前节点的子项,进一步描述硬件设备的子组件或配置
3-reg属性
用于指定设备的寄存器地址和大小,提供设备树设备之间的寄存器映射关系。
(1
)单个值格式:
reg = <address size>;
适用于描述单个寄存器的情况,address 是设备的起始寄存器地址,可以是一个整数或十六进制值。size 表示寄存器的大小,即占用的字节数
(
2
)列表值格式如下所示:
reg = <address1 size1 address2 size2 ...>;
描述多个寄存器区域的地址和大小
4-address-cells 和 size-cells 属性
分别用于指定设备树中地址单元和大小单位的位数
#address-cells 属性它指定了设备树中地址单元的位数。地址单元是设备树中用于表示设备地址的单个单位。解释设备地址时应该使用多少位来表示 一个地址单元
默认情况下,#address-cells
的值为 2,例如,对于一个使用两个 32 位(4 字节)整数表示地址的设备,可以在设备树的根节点
中设置 #address-cells
属性为
<2>
。
#size-cells 属性指定了设备树中大小单元的位数
默认情况下,
#size-cells
的值为
1,表示使用一个单元来表示一个设备的大小。
例如,对于一个使用一个
32
位(
4
字节)整数表示大小的设备,可以在设备树的根节点
中设置
#size-cells
属性为
<1>
。
示例:
node1 {
#address-cells = <1>;
#size-cells = <1>;
node1-child {
reg = <0x02200000 0x4000>;
// 其他属性和子节点的定义
};
};
#address-cells
的值为
<1>
,表示使用一个单元来表示地址,即2个字节。
#size-cells
的值也为
<1>
,表示
使用一个单元来表示大小。
该设备的地址是:0x02200000 地址的大小是:0x4000
node1 {
#address-cells = <2>;
#size-cells = <0>;
node1-child {
reg = <0x0000 0x0001>;
// 其他属性和子节点的定义
};
};
#address-cells = <2>表示用两个单位表示地址,#size-cells = <0>表示不用单元表示大小
地址部分:
0x0000 0x0001
被解释为两个地址单元,其中第一个地址单元为
0x0000
,第二
个地址单元为
0x0001
。
5- model 属性
描述设备的型号或者名称,通常用于标识和区分不同的设备
my_device {
compatible = "vendor,device";
model = "My Device XYZ";
// 其他属性和子节点的定义
};
设备的型号或名称为
"My Device XYZ"
6-status 属性
描述设备或节点的状态
"okay":表示设备或节点正常工作,可用。
"disabled":表示设备或节点被禁用,不可用。
"reserved":表示设备或节点已被保留,暂时不可用。
"fail":表示设备或节点初始化或操作失败,不可用。
设备树可以动态地控制设备的启用和禁用状态。这对于在系统启动 过程中选择性地启用或禁用设备
7-compatible 属性
描述设备的兼容性信息,用于识别设备节点与驱动程序之间的匹配关系。
(
1
)单个字符串值:例如 "vendor,device",指定设备节点与特定厂商的特定设备兼容
(2)字符串列表:例如 ["vendor,device1", "vendor,device2"],指定设备节点与多个厂商设备兼容
(
3
)通配符匹配:例如
"vendor,*"
,用于指定设备节点与特定厂商的所有设备兼容。
my_device {
compatible = "vendor,device";
// 其他属性和子节点的定义
};
my_device
节点具有
compatible
属性,其值为
"vendor,device"
。这个值用于标识设备节点与特定厂商的特定设备兼容。
当设备树被 操作系统或设备管理软件解析时,会根据设备节点的 compatible
属性值来选择适合的驱动程序 进行设备的初始化和配置。
8-aliases 节点
用于定义设备别名,该节点位于设备树的根部,并具有节点路径 /aliases。
aliases {
mmc0 = &sdmmc0;
mmc1 = &sdmmc1;
mmc2 = &sdhci;
serial0 = "/simple@fe000000/seria1@11c500";
};
(
1
)
mmc0
别名与设备树中的
sdmmc0
节点相关联。通过使用别名
mmc0
,其他设备节点
或客户端程序可以更方便地引用
sdmmc0
节点,而不必直接使用其完整路径。
(
2
)
mmc1
别名与设备树中的
sdmmc1
节点相关联。通过使用别名
mmc1
,其他设备节点
或客户端程序可以更方便地引用
sdmmc1
节点,而不必直接使用其完整路径。
......
(
4
)
serial0
别名与设备树中的路径
/simple@fe000000/seria1@11c500
相关联。通过使用
别名
serial0
,其他设备节点或客户端程序可以更方便地引用该路径,而不必记住整个路径字符
串。
其中,& 符号用于引用设备树中的节点。
需要注意的是,
aliases
节点中定义的别名只在设备树内部可见,不能在设备树之外引用。
9-chosen 节点
传递和存储系统引导和配置的相关信息。它位于设备树的根部,并具有路径/chosen
。
(
1
)
bootargs:用于存储引导内核时传递的命令行参数。在引导过程中,操作系统或引导加载程序可以读取该属性来获取启动参数。
(
2
)
stdout-path:用于指定用于标准输出的设备路径。在引导过程中,操作系统可以使用该属性来确定将控制台输出发送到哪个设备,例如串口或显示屏。
(
3
)
firmware-name
:用于指定系统固件的名称。它可以用于标识所使用的引导加载程序或固件的类型和版本。
(
4
)
linux,initrd-start
和
linux,initrd-end
:这些属性用于指定
Linux
内核初始化
RAM
磁盘(initrd
)的起始地址和结束地址。
(
5
)其他自定义属性:
chosen
节点还可以包含其他自定义属性,用于存储特定于系统引
导和配置的信息。这些属性的具体含义和用法取决于设备树的使用和上下文。
chosen {
bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200";
};
chosen
节 点 具 有 一 个 属 性
bootargs
, 其 值 为
"root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200"。
通过这些命令行参数,操作系统或引导加载程序可以配置内核在引导过程中正确地加载 NFS 根文件系统,并将控制台输出发送到指定的串口设备。
10-device_type 节点
描述设备类型的节点,有助于操作系统或其他软件识别和处理设备
常见的设备类型包括但不限于:
(
1
)
cpu
:表示中央处理器。
(
2
)
memory
:表示内存设备。
(
3
)
display
:表示显示设备,如液晶显示屏。
(
4
)
serial
:表示串行通信设备,如串口。
(
5
)
ethernet
:表示以太网设备。
(
6
)
usb
:表示通用串行总线设备。
(
7
)
i2c
:表示使用
I2C (Inter-Integrated Circuit)
总线通信的设备。
(
8
)
spi
:表示使用
SPI (Serial Peripheral Interface)
总线通信的设备。
(
9
)
gpio
:表示通用输入
/
输出设备。
(
10
)
pwm
:表示脉宽调制设备。