Linux(3)Device Tree概念1(上)

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: Linux(3)Device Tree概念1

学习参考推荐 :

基础(☆☆):

雪松(CSDN内核笔记博主) : 📎linux设备树和Pinctrl (1).pptx

https://deepinout.com/android-system-analysis/android-kernel-related/easy-to-understand-linux-device-tree-syntax-detailed.html

https://deepinout.com/android-system-analysis/android-kernel-related/easy-to-understand-common-apis-for-dts.html

https://deepinout.com/android-system-analysis/android-kernel-related/easy-to-understand-linux-dts.html#ftoc-heading-9

进阶(☆☆☆☆):

https://www.cnblogs.com/hellokitty2/p/7406181.html

https://www.cnblogs.com/hellokitty2/p/10992949.html

https://www.cnblogs.com/hellokitty2/p/10999432.html

https://www.cnblogs.com/hellokitty2/p/12501493.html

https://www.cnblogs.com/hellokitty2/p/12952003.html

视频:

https://download.csdn.net/course/detail/9511

0x00 名词解释

缩写

解释

dts

.dts文件是设备树的源文件。文件.dts是一种ASCII文本格式的设备树描述硬件信息。一般都是固定信息,无法变更,无法overlay。

dtsi

.dts文件势必须包含许多共同的部分,Linux内核为了简化,把SoC公用的部分或者多个设备共同的部分一般提炼为.dtsi,类似于C语言的头文件。其他的设备对应的.dts就包括这个.dtsi 。

dtb

.dtb文件是 .dts 被 DTC 编译后的二进制格式的设备树文件,它由Linux内核解析,也可以被bootloader进行解析。

dtbo

overlay编译出来的二进制。

dtbo-base

指定overlay是以哪个dtb为base来覆盖的。

node

树的节点。

property

属性。

0x01 Linux设备树

设备树(Device Tree)简介

设备树的由来

  • 追溯历史

Linux内核源码中,之前充斥着大量的平台相关(platform Device)配置,而这些代码大多是杂乱且重复的,这使得ARM体系结构的代码维护者和内核维护者在发布一个新的版本的时候有大量的工作要做,以至于LinusTorvalds 在2011年3月17日的ARM Linux邮件列表中宣称“Gaah.Guys,this whole ARM thing is a f*cking pain in the ass”这使得整个ARM社区不得不重新慎重考虑平台配置,于是设备树(Device Tree,DT)被ARM社区采用。需要说明的是,设备树最初是由开发固件(Open Firmware)使用的用来向客户程序(通常是一个操作系统)传递数据的通信方法中的一部分内容。在运行时,客户程序通过设备树发现设备的拓扑结构,这样就不需要把硬件信息硬编码到程序中。

  • 设备树简介

设备树是一种描述硬件的数据结构,最早追溯到Linux2.6版本引入的概念,用于实现驱动代码与设备信息相分离,许多硬件的细节可以直接通过它传递给Linux,而不再需要在内核中进行大量的冗余编码,它通过bootloader将硬件资源传给内核,使得内核和硬件资源描述相对独立。

  • 设备树的作用

设备树目的是解耦硬件配置信息,可以描述硬件的数据结构信息、包括CPU的数量和类别、内存基地址和大小、总线和桥、外设连接、中断控制器和中断使用情况、GPIO控制器和GPIO使用情况、Clock控制器和Clock使用情况。另外,设备树对于可热插拔的热备不进行具体描述,它只描述用于控制该热插拔设备的控制器 , 甚至你可以将其看成一个大结构体(这个结构体就是平台,成员就是具体的设备),需要注意的是设备树并不能解决所有的硬件配置问题(例如:机器识别),它只是提供一种语言,将硬件的配置从Linux内核的源码中提取出来。

Linux使用设备树的主要原因如下:

A:平台识别

B:实时配置

C:设备植入

  • 为什么需要设备树?

在设备树出现以前,在老的Linux内核的arch/arm/plat-xxx和arch/arm/mach-xxx中充斥着大量的描述不同板级硬件信息的代码,而这些板级信息对于内核来说不过是一些垃圾代码,因为不同的板级他们的硬件信息都不相同,这些都是硬件特有的信息,对内核而言没有任何的意义,但是往往这部分代码特别的多,造成内核的冗余。所有关于设备的具体信息都要写在驱动里,一旦外围设备变化,驱动代码就要重写。引入了设备树之后,驱动代码只负责处理驱动的逻辑,而关于设备的具体信息存放到设备树文件中,这样,如果只是硬件接口信息的变化而没有驱动逻辑的变化,驱动开发者只需要修改设备树文件信息,不需要改写驱动代码。比如在ARM Linux内,一个.dts(device tree source)文件对应一个ARM的machine,一般放置在内核的"arch/arm/boot/dts/"目录内 这个文件可以通过$make dtbs命令编译成二进制的.dtb文件供内核驱动使用,设备树的引入就是为了解决这个问题。

基于同样的软件分层设计的思想,由于一个SoC可能对应多个machine,如果每个machine的设备树都写成一个完全独立的.dts文件,那么势必相当一些.dts文件有重复的部分,为了解决这个问题,Linux设备树目录把一个SoC公用的部分或者多个machine共同的部分提炼为相应的.dtsi文件。这样每个.dts就只有自己差异的部分,公有的部分只需要"include"相应的.dtsi文件, 这样就是整个设备树的管理更加有序。

设备树解耦目标和overlay规则

vendor相关修改,完全独立出来,禁止在soc原生的dtsi中修改,只允许以dtbo的方式存在;

该节内容为overlay机制原生规则,罗列出来帮助驱动工程师解决各种异常问题。

规则1:对于同一个节点的设置情况,dts中的配置会覆盖dtsi中的配置;

规则2:对于节点的修改,先引用后修改;例如原生节点定义如下:

需要在reserved-memory节点中添加一个新的节点或者直接修改reserved-memory节点的属性,都需要先引用reserved_memory节点(注意节点的引用名与节点名可以不一致)

如上案例中,引用reserved-memory节点,并删除了ranges属性,删除了hyp_mem节点,新增了kboot_uboot_logmem节点;

规则3:只有引用申明的节点,在dtsi中“&节点名”才会生效,否则引用点将不生效;例如:firmware节点下fstab 节点的定义如下

firmware:firmware中“:”之前的内容为引用申明。只有申明后才可以在其他地方引用。Firmware下的fstab 节点没有引用声明,在其他位置就不可以引用。如果要修改fstab节点里的属性,引用firmware节点然后修改其中属性,案例如下:

对于同一个节点的设置情况,dts文件中的内容会覆盖dtsi中的。

设备树文件类型 dts、dtsi、dtc、dtb

设备树的主要优势:

对于同一SOC的不同主板,只需更换设备树文件.dtb或者.dtbo文件即可实现不同主板的无差异支持,而无需更换内核文件,实现了内核和不同板级硬件数据的拆分。设备树包含DTC(device tree compiler),DTS(device tree source)和DTB(device tree blob)。

dtc、dts/dtsi和dtb的关系:

dts和dtsi源文件会经过dtc编译器编译成dtb二进制文件,dtb文件最后会被放到系统中被内核解析。

DTS(device tree source)

DTS: .dts文件是设备树的源文件。文件.dts是一种ASCII文本格式的设备树描述 ,一个.dts文件对应一个ARM的设备, 一般放置在内核的arch/arm/boot/dts/目录中 。由于一个SoC可能对应多个设备(一个SoC可以对应多个产品和电路板),这些.dts文件势必须包含许多共同的部分,Linux内核为了简化,把SoC公用的部分或者多个设备共同的部分一般提炼为.dtsi,类似于C语言的头文件。其他的设备对应的.dts就包括这个.dtsi 。

目录:arch/arm64/boot/dts/mediatek/auto2735evb.dts

DTC(device tree compiler)

DTC是将.dts编译为.dtb的工具,相当于gcc。DTC的源代码位于内核的scripts/dtc目录中, 在Linux内核使能了设备树的情况下, 编译内核的时候主机工具DTC会被编译出来, 对应于scripts/dtc/Makefile中“hostprogs-y:=dtc”这一hostprogs的编译目标。

生成dts文件对应的dtb文件dtc –I dts –O dtb –o xxx.dtb xxx.dts

反过来即可生成dts文件dtc –I dtb –O dts –o xxx.dts xxx.dtb

DTB(device tree blob)

DTB:

.dtb文件是 .dts 被 DTC 编译后的二进制格式的设备树文件,它由Linux内核解析,也可以被bootloader进行解析。通常在我们为电路板制作NAND、SD启动映像时,会为.dtb文件单独留下一个很小的区域以存放之,之后bootloader在引导内核的过程中,会先读取该.dtb到内存。

DTB(device tree blob)的格式

FDT_BEGIN_NODE和FDT_END_NODE标识node节点的起始和结束,FDT_PROP标识node节点下面的属性起始符,FDT_END标识Device Tree的结束标识符。因此,对于每个node节点的tag标识符一般为FDT_BEGIN_NODE,对于每个node节点下面的属性的tag标识符一般是FDT_PROP。

设备树语法规则

1. 设备树框架

设备树用树状结构描述设备信息,它有以下几种特性:

  • 每个设备树文件都有一个根节点,每个设备都是一个节点。
  • 节点间可以嵌套,形成父子关系,这样就可以方便的描述设备间的关系。
  • 每个设备的属性都用一组key-value对(键值对)来描述。
  • 每个属性的描述用;结束

所以,一个设备树的基本框架可以写成下面这个样子,一般来说,/表示板子,它的子节点node1表示SoC上的某个控制器,控制器中的子节点node2表示挂接在这个控制器上的设备(们)。

DeviceTree的结构非常简单,由两种元素组成:Node(节点)Property(属性)

[label:] node-name[@unit-address] {
[properties definitions]
[child nodes]
}
/{ //根节点
node1{ //node1是节点名,是/的子节点
key=value; //node1的属性
...
node2{ //node2是node1的子节点
key=value; //node2的属性
...
}
} //node1的描述到此为止
node3{
key=value;
...
}
}

2. 设备节点名

在设备树中节点命名格式如下:

node-name@unit-address

node-name: 是设备节点的名称,为ASCII字符串,节点名字应该能够清晰的描述出节点的功能

unit-address: 一般表示设备的地址或寄存器首地址,如果某个节点没有地址或者寄存器的话 “unit-address” 可以不要。

理论个节点名只要是长度不超过31个字符的ASCII字符串即可,此外

Linux内核还约定设备名应写成形如[@]的形式,其中name就是设备名,最长可以是31个字符长度。unit_address一般是设备地址,用来唯一标识一个节点,下面就是典型节点名的写法

每个设备树文件只有一个根节点,其他所有的设备节点都是它的子节点,它的路径是 /。根节点有以下属性:


Linux(3)Device Tree概念1(下)+https://developer.aliyun.com/article/1488397

相关文章
|
4月前
|
Linux Windows
Linux01---目录结构,Linux系统下只有一个最顶级的树/,Windows系统有盘符概念,而Linux系统没有盘符概念,整个系统都在/根目录下,Linux 系统写法 /user/local
Linux01---目录结构,Linux系统下只有一个最顶级的树/,Windows系统有盘符概念,而Linux系统没有盘符概念,整个系统都在/根目录下,Linux 系统写法 /user/local
|
1月前
|
Ubuntu Java Linux
Linux操作系统——概念扫盲I
Linux操作系统——概念扫盲I
42 4
|
3月前
|
存储 缓存 Linux
在Linux中,文件系统概念是什么?
在Linux中,文件系统概念是什么?
|
3月前
|
Linux Shell 调度
【在Linux世界中追寻伟大的One Piece】Linux进程概念
【在Linux世界中追寻伟大的One Piece】Linux进程概念
40 1
|
3月前
|
存储 安全 Linux
在Linux中,用户和组的概念是什么?
在Linux中,用户和组的概念是什么?
|
3月前
|
Linux 持续交付 虚拟化
在Linux中,Docker和容器虚拟概念是什么?
在Linux中,Docker和容器虚拟概念是什么?
|
3月前
|
安全 Linux 调度
在Linux中, 用户和组的概念是什么?作用分别是什么?
在Linux中, 用户和组的概念是什么?作用分别是什么?
|
5月前
|
存储 Shell Linux
Linux进程概念(下)
本文详细的介绍了环境变量和进程空间的概念及其相关的知识。
37 0
Linux进程概念(下)
|
4月前
|
缓存 Linux 编译器
【Linux】多线程——线程概念|进程VS线程|线程控制(下)
【Linux】多线程——线程概念|进程VS线程|线程控制(下)
66 0