Linux 学习笔记:设备树 — 概述

一、什么是设备树

设备树(Device Tree)采用树形结构描述板级设备,也就是开发板上的设备信息,比如CPU 数量、内存基地址、IIC 接口上接了哪些设备、SPI 接口上接了哪些设备等等。

设备树将描述板级硬件信息的内容都从Linux 内核中分离开来,用一个专属的文件格式来描述,文件扩展名为 .dts

在这里插入图片描述

如上图所示,树的主干就是系统总线,IIC 控制器、GPIO 控制器、SPI 控制器等都是接到系统主线上的分支。IIC 控制器又分为IIC1 和IIC2 两种,其中IIC1 上接了FT5206 和 AT24C02 这两个IIC 设备,IIC2 上只接了MPU6050 这个设备。

二、DTS、DTB、DTC

2.1 DTS

DTS 是设备树文件。

2.2 DTB

DTB 是将DTS 编译以后得到的二进制文件。

2.3 DTC

将.c 文件编译为.o 需要用到gcc 编译器,那么将.dts 编译为.dtb, 需要的是DTC 工具。DTC 工具源码在Linux 内核的script/dtc 目录下

编译dtc 工具的makefile

在scripts/dtc/Makefile 文件内容如下:

hostprogs-y	:= dtc
always		:= $(hostprogs-y)

dtc-objs	:= dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
		   srcpos.o checks.o util.o
dtc-objs	+= dtc-lexer.lex.o dtc-parser.tab.o

......

DTC 工具依赖于dtc.c 、flattree.c 、fstree.c 等文件,最终编译并链接出DTC 这个主机文件。

2.4 编译DTS 文件

如果要编译DTS 文件的话,只需要进入到Linux 源码根目录下,然后执行如下命令:

make all

或者:

make dtbs

make all 命令是编译Linux 源码中的所有东西,包括zImage.ko驱动模块以及设备树,如果只编译设备树的话建议使用 “make dtbs” 命令。

三、DTS 语法

我们基本上不会从头到尾重写一个.dts 文件,大多时候是直接在SOC 厂商提供的.dts 文件上进行修改。

关于设备树的详细语法规则,参考《Devicetree SpecificationV0.2.pdf 》和 《Power_ePAPR_APPROVED_v1.12.pdf》这两份文档。

3.1 .dtsi 头文件

和C语言一样,设备树也支持头文件,设备树的头文件扩展名为.dtsi 。在imx6ull-alientek-emmc.dts 中有如下所示内容:

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

在 .dts 设备树文件中,可以通过 ”#include ” 来引用 .h.dtsi , .dts 文件。只是,我们在编写设备树头文件的时候最好选择.dtsi 后缀。

一般 .dtsi 文件用于描述SOC 的内部外设信息,比如CPU 架构、主频、外设寄存器地址范围,比如UART、IIC 等等。比如imx6ull.dtsi 就是描述 I.MX6ULL 这款SOC 内部外设情况。

3.2 设备节点

设备树是采用树形结构来描述板子上的设备信息的文件,每个设备都是一个节点,叫做设备节点,每个节点都通过一些属性信息来描述节点信息,属性就是键 — 值对。以下是从imx6ull.dtsi 文件中缩减出来的设备树文件内容:

/ {
	aliases {
		can0 = &flexcan1;
	};

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

		cpu0: cpu@0 {
			compatible = "arm,cortex-a7";
			device_type = "cpu";
			reg = <0>;
	};

	intc: interrupt-controller@00a01000 {
		compatible = "arm,cortex-a7-gic";
		#interrupt-cells = <3>;
		interrupt-controller;
		reg = <0x00a01000 0x1000>,
		      <0x00a02000 0x100>;
	};
}
  • 第1行,”/” 是根节点,每个设备树文件都只有一个根节点。imx6ull.dtsi 和 imx6ull-alientek-emmc.dts 这两个文件都有一个 “/” 根节点,这两个根节点的内容会合并成一个根节点。

  • aliases、cpus、intc 是三个子节点,在设备树中节点命名格式如下:

    node-name@unit-address
    
    1. node-name : 是节点名字,为ASCII 字符串,节点名字应该能够清晰的描述出节点的功能。
    2. unit-address: 一般表示设备的地址或寄存器首地址。
  • 节点标签

    但是我们看到的节点命名却是如下所示:

    label:node-name@unit-address
    

    “:” 前面的是节点标签(label),“:” 后面的才是节点名字。引入label 的目的是为了方便访问节点,可以直接通过**&label** 来访问这个节点。

  • 常见的属性形式

    每个节点都有不同属性,不同的属性又有不同的内容,属性都是键值对,值可以为空或任意的字节流。

    1. 字符串

      compatible="arm,cortex-a7"
      
    2. 32位无符号整数

      reg = <0>;
      

      上述代码设置reg 属性的值为0,reg 的值也可以设置为一组值,比如:

      reg = <0 0x12345 100>
      
    3. 字符串列表

      属性值也可以为字符串列表,字符串和字符串之间采用“,” 隔开,如下所示:

      compatible="fsl,imx6ull-gpmi-nand","fsl,imx6ul-gpmi-nand";
      

      上述代码设置属性 compatible 的值为"fsl,imx6ull-gpmi-nand",“fsl,imx6ul-gpmi-nand”。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gdut_llkkyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值