初识设备树

目录:

一、加载Linux(有无设备树)

二、设备树入门知识

一、加载Linux(有无设备树)

没有设备树的时候(以ARM架构为例):

- 内核在源码里记录了所有硬件相关的信息(芯片型号、内存大小,各种控制器和外设等);

- booloader只需要加载一个kernel image(例如uImage、zImage等),然后跳转到kernel image的起始地址就可以开始执行内核代码了。

- bootloader在加载kernel image前,会先准备好一些供内核使用的信息,这些信息被称为ATAGS,典型的ATAGS有:启动参数(command line)、内存大小、内存位置。bootloader在跳转到kernel image 前,会把ATAGS的地址放在r2寄存器里,内核启动时通过读r2寄存器获取ATAGS;因为ATAGS很重要(内存的起始地址和大小不确定的话内核寸步难行),内核必须尽早获取ATAGS。

- bootloader在加载kernel image前,会将单板型号(machine type,一个整型数)放在r1寄存器里,内核启动时获取到machine type integer,进而找到用于描述单板的struct machine_desc,struct machine_desc里包含了所有硬件信息:

- 以U-boot为例,U-boot加载内核的命令:bootm <kernel image addr>,没有设备树时加载内核的示意图如下:

为什么要引入设备树?

引入设备树前:

- 所有单板相关的硬件信息都是hard-coded,这导致内核必须收集单板所有的配置,每当有一点点非常小的改动时,就需要生成一个新的kernel image。例如产品里某个I2C设备是可插拔的,那么不管这个I2C设备是否存在,工程师们都会把该I2C设备的描述代码添加到内核中,这样的内核是臃肿的。

- 不同平台需要不同的Kernel image,各Linux发行版维护工作繁重。

引入设备树后:

- 对于芯片厂商:

不再需要编写machine support code(例如ARM架构的芯片的arch/arm/mach-*),只需要关注在设备驱动的开发上,machine_desc由内核自动创建;

- 对于开发板定制商:

1) 适配更容易了,芯片厂提供的多份DTB配置里可能有一份可直接或者简单修改就运行在定制板上;

2) 不再需要为定制板分配一个全局的machine id,取而代之的是在设备树里添加 <vendor>,<boardname>;

3) 许多单板相关的配置都集中在设备树或者设备驱动里了,和machine代码隔离开;

有了设备树后(以ARM架构为例):

- 内核源码里不再包含任何关于某个单板的硬件信息,每个单板的硬件信息都独立地保存在1个二进制文件里:device tree blob(简称DTB文件,一般以.dtb为后缀)。DTB文件由dts文件编译而来,ARM架构的单板的dts文件位于arch/arm/boot/dts

- bootloader启动内核时需要加载2个文件:kernel image和DTB文件。DTB文件的起始地址是通过r2寄存器传递给内核的,之前保存在ATAGS的里信息(command line、memory info)现在都直接包含在DTB文件里了。

- bootloader 不再需要传递machine type给内核了,但是并不是说内核里不再需要machine type integer和struct machine_desc。只是内核现在可以通过解析DTB的方式自行构造出出struct machine_desc,相关代码:

这里的__atags_pointer = r2寄存器 = dt_phys = DTB文件的地址。在没有设备树之前__atags_pointer是用来保存ATAGS的地址的,有了设备树之后,它能同时兼容ATAGS和DTB地址,这是因为 DTB 文件里有magic number(OF_DT_MAGIC),内核通过调用函数__vet_atags()来判断r2寄存器保存的是atags还是dtb的地址;

- 以U-boot为例,U-boot加载内核的命令:bootm <kernel image addr> - <dtb addr>,有设备树后加载内核的示意图如下:

DT booting的兼容模式(目的是为了兼容旧版本的booloader,旧版本的bootloader不支持传dtb

- 许多芯片的供货时长会有10年甚至以下,这些旧款芯片的BSP版本非常旧,例如Uboot-1.1.6 + Linux-2.6。而当你想改用新版本的内核(例如 Linux-4.14)又不想丢弃芯片厂商提供的功能齐全的U-boot时,Uboot-1.1.6 是否可以加载 Linux-4.14 的 kernel image 和 DTB 呢?答案是可以的。

- 内核提供了一种兼容机制:

CONFIG_ARM_APPENDED_DTB。该配置项会让内核从kernel image的末尾去寻找DTB,将kernel image和DTB拼接起来的命令如下:

$ cat zImage xxx.dtb > zImage-with-dtb

- 在CONFIG_ARM_APPENDED_DTB配置项之下,还有一个可选的配置项:CONFIG_ARM_ATAG_DTB_COMPAT。此配置项会让内核读取bootloader传递过来的ATAGS,然后更新到DT里。

- 如何判断你当前使用的U-boot是否支持加载DTB?

一般来说查看一下U-boot自带的帮助说明即可:

但是,很多芯片厂商的U-boot是定制过的,有可能没有使用U-boot里自带的标准命令来加载kernel image,这种情况就只能自行分析原厂添加的相关的代码,从源码里才能确定原厂的U-boot是否有加载DTB的能力,并且确定在加载DTB前是否改动过DTB。

二、设备树入门知识

什么是设备树?

设备树是一个易读的硬件描述文件,格式类似JSON,树状结构,树上的每一个node代表硬件描述里的一个 device。一个 node 会包含多个 properties,properties可以没有value(即只有key没有value,足够用来表示bool值),也可以是一对key-value,示意图如下:

设备树入门知识

- DTS 是 Device Tree Source 的缩写,对于ARM架构,DTS文件位于arch/arm/boot/dts,在该目录下,.dts文件用于定义板级的硬件信息,.dtsi文件用于定义芯片级的硬件信息,.dtsi文件会被.dts文件包含,以BeagleBone board的DTS为例:

上图可以看出,同一设备节点(如uart0:serial@44e09000)可以分开写,但最终编译dtb的时候,会将其合并

- 设备树编译器scripts/dtc可将 DTS 文件编译成 DTB文件(Device Tree Blob),编译命令如下:

$ make zImage dtbs ARCH=arm CROSS_COMPILE=arm-linux-

arch/arm/boot/dts/Makefile里包含了所有应该的生成的DTB文件,

- 在目标设备上查看设备树:

- 在目标设备上的打印整个设备树:

$ dtc -I fs /proc/device-tree

$ dtc -I fs /sys/firmware/devicetree/base/

2个命令的效果一样。

一个简单的设备树节点示例:

设备树节点:

设备驱动端:

- 设备树节点和设备驱动是通过compatible属性绑定在一起的。

- 变量of_match_table的类型为struct of_device_id *,指定的是此驱动支持的设备列表;

- 既然一个驱动可支持多个设备,不同设备的初始化过程是不同的,那么驱动端应该有能力知道当前要probe的是哪个设备:调用of_match_device()就可以获取matching device的of_device_id,进而决定读取哪些属性;

- 获取设备树里的属性:

设备树的 bindings

- bindings 用于定义在设备树中如何表示某一类或者某一个特定的设备;

- 设备树节点中的 compatible 属性用于表示该节点下的所有bindings会被哪个设备驱动所使用;

- bindings可以理解为某个节点支持的所有properties,某一个设备可能只需要部分properties就能被完整地描述,即properties分为强制和可选的;

- 每一个内核子系统或者framework都有自己的bindings,所有内核支持的bindings说明文档都位于Documentation/devicetree/bindings,示例如下:

Documentation/devicetree/bindings/serial/snps-dw-apb-uart.txt

到此,设备树的一些基本知识就算描述完毕了,关于设备树还有很多值得挖掘的知识,以后再慢慢完善吧。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值