Linux DTS (Device Tree Source)设备树源码

本文详细介绍了Linux DTS设备树的概念、文件格式、语法及常见操作函数等内容。DTS设备树是一种描述硬件的数据结构,用于替代内核中的硬件编码,提高系统的灵活性和可维护性。

1. 简介

  • 概念:设备树(Device Tree),将这个词分开就是“设备”和“树”,描述设备树的文件叫做 DTS(Device Tree Source),这个 DTS 文件采用树形结构描述板级设备,也就是开发板上的设备信息,比如 CPU 数量、 内存基地址、IIC 接口上接了哪些设备、SPI 接口上接了哪些设备等等。如下图所示
    在这里插入图片描述

  • 树的主干就是系统总线,IIC 控制器、GPIO 控制器、SPI 控制器等都是接 到系统主线上的分支。IIC 控制器有分为 IIC1 和 IIC2 两种,其中 IIC1 上接了 FT5206 和 AT24C02 这两个 IIC 设备,IIC2 上只接了 MPU6050 这个设备。DTS 文件的主要功能就是按图所示的结构来描述板子上的设备信息。

  • DTS 是为 Linux 提供一种硬件信息的描述方法,以此代替源码中的 硬件编码 (hard code)。DTS 即 Device Tree Source 设备树源码, Device Tree 是一种描述硬件的数据结构,起源于 OpenFirmware (OF). 在 Linux 2.6 中, ARM 架构的板级硬件细节过多的被硬编码在 arch/arm/plat-xxx 和 arch/arm/mach-xxx (比如板上的 platform 设备,resource, i2c_board_info, spi_board_info 以及各种硬件的 platform_data), 这些板级细节代码对内核来讲只不过是垃圾代码。而采用 Device Tree 后, 许多硬件的细节可以直接透过它传递给 Linux,而不再需要在 kernel 中 进行大量的冗余编码。

  • DTS设备树描述文件中什么代表总线,什么代表设备

    • 设备:一个含有compatible属性的节点就是一个设备
    • 总线:包含一组设备节点的父节点即为总线

1.1 引入DTS的原因

  • 对ARM平台的相关code做出如下相关规范调整,这个也正是引入DTS的原因:
    • ARM的核心代码仍然保存在arch/arm目录下
    • ARM SoC core architecture code保存在arch/arm目录下
    • ARM SOC的周边外设模块的驱动保存在drivers目录下
    • ARM SOC的特定代码在arch/arm/mach-xxx目录下
    • ARM SOC board specific的代码被移除,由DeviceTree机制来负责传递硬件拓扑和硬件资源信息。
  • 本质上,Device Tree改变了原来用hardcode方式将HW 配置信息嵌入到内核代码的方法,改用bootloader传递一个DB的形式。
  • 如果我们认为kernel是一个black box,那么其输入参数应该包括:
    • 识别platform的信息
    • runtime的配置参数
    • 设备的拓扑结构以及特性
  • 对于嵌入式系统,在系统启动阶段,bootloader会加载内核并将控制权转交给内核,此外, 还需要把上述的三个参数信息传递给kernel,以便kernel可以有较大的灵活性。在linux kernel中,Device Tree的设计目标就是如此。

1.2 文件格式

缩写 描述
DTS(.dts) 设备树源文件(描述板级信息:开发板上有哪些 IIC 设备、SPI 设备等)
DTS(.dtb) 设备树编译文件
.dtsi 设备树头文件(描述SOC级信息:CPU 架构、主频、外设寄存器地址范围等)
DTC 将.dts 编译为.dtb:DTC的源代码位于内核的scripts/dtc目录,在Linux内核使能了Device Tree的情况下, 编译内核的时候主机工具dtc会被编译出来,对应scripts/dtc/Makefile中的“hostprogs-y := dtc”这一hostprogs编译target。 在Linux内核的arch/arm/boot/dts/Makefile中,描述了当某种SoC被选中后,哪些.dtb文件会被编译出来
  • 设备树相关文件均在 arch/arm/boot/dts/ 文件夹
  • DTC 工具源码在 Linux 内核的 scripts/dtc 目录下
  • DTC 工具依赖于 dtc.c、flattree.c、fstree.c 等文件,最终编译并链接出 DTC 这个主机文件
  • 在 arch/arm/boot/dts/Makefile 中新增需要编译的DTS文件。
  • 如果要编译 DTS 文件的话只需要进入到 Linux 源码根目录下,然后执行如下命令:
    • make all:编译 Linux 源码中的所有东西,包括 zImage,.ko 驱动模块以及设备 树
    • make dtbs:仅编译设备树

2. DTS语法

  • DTS中常用符号的含义
符号 描述
/ 根节点
@ 如果设备有地址,则由此符号指定
& 引用节点
冒号前的label是为了方便引用给节点起的别名,此label一般使用为&label
属性名称中可以包含逗号。如compatible属性的名字 组成方式为”[manufacturer], [model]”,加入厂商名是为了避免重名。自定义属性名中通常也要有厂商名,并以逗号分隔。
# #并不表示注释。如 #address-cells ,#size-cells 用来决定reg属性的格式
空属性并不一定表示没有赋值。如 interrupt-controller 一个空属性用来声明这个node接收中断信号数据类型
”” 引号中的为字符串,字符串数组:”strint1”,”string2”,”string3”
< > 尖括号中的为32位整形数字,整形数组<12 3 4>
[ ] 方括号中的为32位十六进制数,十六机制数据[0x11 0x12 0x13] 其中0x可省略

2.1 .dtsi头文件

  • 在 .dts 设备树文件中,可以通过“#include ”来引用 .h 、 .dtsi 和 .dts 文件。
  • .dtsi 文件用于描述 SOC 的内部外设信息,比如 CPU 架构、主频、外设寄存器地址范围,比如 UART 、 IIC 等等。

2.2 设备节点

  • 设备树是采用树形结构来描述板子上的设备信息的文件,每个设备都是一个节点,叫做设备节点,每个节点都通过一些属性信息来描述节点信息,属性就是 键值对。每个节点都有不同属性,不同的属性又有不同的内容,属性都是键值对,值可以为空或任意的字节流。
  • .dts举例说明
/ {
   
    
    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>;
    };
}
  • “/”是根节点,每个设备树文件只有一个根节点。

2.2.1 设备树中节点命名格式

  • 节点标签:节点名@设备的地址或寄存器首地址
label: node-name@unit-address ​​​
// e.g.:
cpu0:cpu@0 

2.2.2 设备树源码中常用的几种数据类型

1) 字符串

compatible ="arm,cortex-a7";

上述代码设置 compatible 属性的值为字符串“arm,cortex-a7”。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值