设备树:
本质是一个文件,包含很多节点,每个节点里边是对设备属性的描述(包括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 :表示脉宽调制设备。