zl程序教程

您现在的位置是:首页 >  系统

当前栏目

Linux - Devicetree规范: 结构介绍和标准属性

Linux属性标准 介绍 结构 规范
2023-09-11 14:22:09 时间

参考:

Specifications - DeviceTree

Release v0.3: Devicetree Specification 0.3 · devicetree-org/devicetree-specification · GitHub

devicetree-specification-changebars-v0.3.pdf (Devicetree Specification Release v0.3-40-g7e1cc17)

鸣谢

devicetree.org技术指导委员会要感谢许多通过写作、技术讨论和审查为本规范的制定做出贡献的个人和公司。

我们要感谢开发和发布ePAPR的power.org平台架构技术委员会。ePAPR的文本被用作本文档的出发点。

Devicetree规范的重要方面是基于开放固件工作组所做的工作,该工作组为IEEE-1275开发了bindings功能。我们要感谢他们的贡献。

我们还要感谢PowerPC和ARM Linux社区的贡献,他们开发并实施了扁平化的devicetree概念。

注:ePAPR是一个文档:Power.org™ Standard for Embedded Power Architecture™ Platform Requirements。

第一章 介绍 Introduction

1.1 目的和范围

为了初始化和启动一个计算机系统,各种软件组件相互作用。固件可以在将控制权移交给操作系统、bootloader(引导程序)或hypervisor(管理程序)等软件之前,对系统硬件进行低级别的初始化。

Bootloaders和hypervisors可以接着加载和转移控制权给操作系统。标准的、一致的接口和约定促进了这些软件组件之间的相互作用。在本文件中,boot program(引导程序)这个术语被用来泛指一个软件组件,它初始化系统状态并执行另一个被称为客户程序的软件组件。boot program的例子包括:固件(firmware)、bootloaders和hypervisor。客户端程序的例子包括:bootloaders、hypervisor、操作系统和特殊用途程序。一个软件可能既是客户程序又是启动程序(例如,hypervisor)。

这个规范,即 Devicetree 规范(DTSpec),提供了一个完整的boot program到客户端程序的接口定义,结合了最低的系统要求,方便了各种系统的开发。

这个规范是针对嵌入式系统的要求的。一个嵌入式系统通常由系统硬件、操作系统和应用软件组成,这些都是为执行固定的、特定的任务集而定制的。这与通用计算机不同,通用计算机的设计是由用户通过各种软件和I/O设备来定制。嵌入式系统的其他特点可能包括:

 - 一套固定的I/O设备,可能为应用程序高度定制

 - 针对尺寸和成本优化的系统电路板

 - 有限的用户接口

 - 资源限制,如有限的内存和有限的非易失性存储空间

 - 实时响应限制

 -  使用各种各样的操作系统,包括Linux、实时操作系统和自定义或专有操作系统

本文档的组织

第1章介绍了DTSpec所指定的架构。

第2章介绍了设备树的概念,并描述了其逻辑结构和标准属性。

第3章规定了符合DTSpec的设备树所需的设备节点的基本集合的定义。

第4章描述了某些类别的设备和特定设备类型的设备绑定。

第5章规定了devicetrees的DTB编码。

第6章规定了DTS源码所用语言。

本文件中使用的惯例

"shall"一词用于表示为了符合标准而必须严格遵守的强制性要求,并且不允许偏离这些要求("shall" equals "is required to")。

should这个词用来表示在几种可能性中,有一种被推荐为特别合适,而不提及或排除其他可能性;或者表示某种行动方案是首选,但不一定是必须的;或者表示某种行动方案是不提倡的(使用否定形式),但不禁止(“should” equals “is recommended that”)。

May一词用于表示在标准的范围内允许的行动过程(“may” equals “is permitted”)。

devicetree结构的例子经常以Devicetree语法形式(Devicetree Syntax form)显示。请见第六章。

1.2 与IEEE 1275和ePAPR的关系

DTSpec与IEEE 1275 Open Firmware standard (开放固件标准)有一定的关系,后者全称是:IEEE Standard for Boot (Initialization Configuration) Firmware: Core Requirements and Practices [IEEE1275].

原始的IEEE 1275规范及其衍生物,如CHRP和PAPR,解决了通用计算机的问题,如一个单一版本的操作系统如何在同一家族的几个不同的计算机上工作,以及从用户安装的I/O设备加载操作系统的问题。

由于嵌入式系统的性质,开放的通用计算机所面临的这些问题中的一些并不适用。DTSpec省略了IEEE 1275规范中的一些明显的功能:

 - 插件式设备驱动程序

 - FC代码

 - 基于Forth的可编程的开放固件用户接口

 - FCode的调试

 - 操作系统调试

从IEEE 1275中保留的是devicetree架构的概念,通过这些概念,启动程序boot program可以描述系统硬件信息并将其传达给客户程序client program,从而消除了客户程序对系统硬件硬编码描述的需要。

本规范部分取代了ePAPR规范。ePAPR记录了devicetree是如何被Power ISA使用的,包括一般概念和Power ISA的具体绑定。本文档的文本参考了ePAPR,但删除了架构的具体绑定,或将其移至附录中。

1.3 32位和64位支持

DTSpec支持的CPU包括32位和64位寻址能力。在需要的地方,DTSpec的章节描述了对32位和64位寻址有关的需求和研究。

1.4 术语的定义 / Definition of Terms

AMP  Asymmetric Multiprocessing. 非对称多处理。计算机可用的CPU被分成若干组,每组运行不同的操作系统镜像。这些CPU可能相同,也可能不相同。

boot CPU  引导CPU. 引导程序(boot program)将客户程序入口点指向的第一个CPU。

Book III-E  嵌入式环境。Power ISA中定义监督器指令和相关设施的部分,用于嵌入式Power处理器的实现。 

boot program 引导程序。用于泛指一个软件组件,它初始化系统状态并执行另一个被称为客户程序的软件组件。引导程序的例子包括:固件(firmware)、引导程序(bootloaders)和管理程序(hypervisors)。

client program 客户端程序。通常包含应用程序或操作系统软件的程序。客户端程序的例子 包括:引导器(bootloaders)、管理程序(hypervisors)、操作系统和特殊用途程序(special purpose programs)。

cell 由32位组成的信息单位。

DMA     Direct memory access, 直接内存访问

DTB    Devicetree blob. 设备树的紧凑二进制表示。

DTC    Devicetree编译器。一个开源工具,用于从DTS文件创建DTB文件。

DTS Devicetree 语法。由DTC消费的devicetree的文本表示。见附录A Devicetree源格式(版本1)。

effective address 有效地址。由处理器存储访问或分支指令计算出的内存地址。

physical address   物理地址。处理器用来访问外部设备的地址,通常是一个内存控制器。

Power ISA   Power Instruction Set Architecture. Power指令集合架构。

interrupt specifier 中断指定器. 描述一个中断的属性值。通常包括指定中断编号和灵敏度以及触发机制的信息。

secondary CPU  客户程序所使用的除了启动CPU以外的其他CPU,被认为是二级CPU。

SMP   Symmetric multiprocessing. 对称多处理。一种计算机架构,两个或多个相同的CPU可以共享内存和IO, 并在一个单一的操作系统下运行。

SoC   System on a chip。单个计算机芯片,集成了一个或多个CPU核心以及其他一些外围设备。

unit address 单位地址。节点名称的一部分,指定节点在父节点的地址空间中的地址。

quiescent CPU  静止的CPU处于一种状态,它不能干扰其他CPU的正常运行,同时它的状态也不能被其他运行中的CPU的正常操作的响,除非通过明确的方法启用或重新启用静止的CPU。

第二章 设备树 THE DEVICETREE

2.1 概览

DTSpec指定了一个叫做devicetree的结构来描述系统硬件。启动程序将devicetree加载到客户程序的内存中,并将devicetree的指针传递给客户。

本章描述了devicetree的逻辑结构,并指定了一套用于描述设备节点的基本属性。第3章规定了符合DTSpec的devicetree所要求的某些设备节点。第4章描述了DTSpec定义的设备绑定--代表某些设备类型或设备类别的要求。第5章描述了devicetree的内存编码。

devicetree是一个树形数据结构,其节点描述了系统中的设备。每个节点都有描述所代表设备特性的属性/值对。每个节点都有确切的一个父节点,除了根节点,它没有父节点。

符合DTSpec的devicetree描述了系统中的设备信息,这些信息不一定能被客户程序动态地检测到。例如,PCI的结构使客户端能够探测和检测连接的设备,因此描述PCI设备的devicetree节点可能不需要。然而,如果系统中的PCI主机桥设备不能被探测到,则需要一个设备节点来描述它。

例子

图2.1显示了一个简单的设备树的例子,它几乎完整到可以启动一个简单的操作系统,描述了平台类型、CPU、内存和一个UART。设备节点显示了每个节点内的属性和值。

图2.1: 设备树实例 / Fig. 2.1: Devicetree Example

2.2 Devicetree结构和约定 / Devicetree Structure and Conventions

2.2.1 节点名称 / Node Names

节点名称要求

设备树中的每个节点都按照以下惯例命名:

node-name@unit-address

node-name组件指定了节点的名称。它的长度为1到31个字符,并且只由表2.1中的字符集组成。

表2.1: 节点名称的有效字符

节点名称应以小写或大写字符开始,应描述设备的一般类别。

名称中的单位地址部分是针对节点所处的总线类型的。它由表2.1中的字符集的一个或多个ASCII字符组成。单位地址必须与节点的reg属性中指定的第一个地址相匹配。如果节点没有reg属性,则必须省略@unit-address,仅用node-name就可以将该节点与树中同级别的其他节点区分开来。特定总线的绑定可能会对reg和unit-address的格式规定更多、更具体的要求。

在节点名称没有@unit-address的情况下,节点名称和树中同级的属性名称也要保持不同,是唯一可识别的。

根节点没有节点名或单位地址。它由一个正斜杠(/)标识。

图2.2: 节点名称示例

在图2.2中:

- 名称为cpu的节点通过其单位地址值0和1来区分。

- 名为ethernet的节点通过其单位地址值fe002000和fe003000来区分。

2.2.2 通用名称建议

节点的名称应该具有一定的通用性,反映出设备的功能,而不是其具体的编程模型。如果合适的话,该名称应该是以下选择之一:

• adc

• accelerometer

• air-pollution-sensor

• atm

• audio-codec

• audio-controller

• backlight

• bluetooth

• bus

• cache-controller

• camera

• can

• charger

• clock

• clock-controller

• co2-sensor

• compact-flash

• cpu

• cpus

• crypto

• disk

• display

• dma-controller

• dsi

• dsp

• eeprom

• efuse

• endpoint

• ethernet

• ethernet-phy

• fdc

• flash

• gnss

• gpio

• gpu

• gyrometer

• hdmi

• hwlock

• i2c

• i2c-mux

• ide

• interrupt-controller

• iommu

• isa

• keyboard

• key

• keys

• lcd-controller

• led

• leds

• led-controller

• light-sensor

• lora

• magnetometer

• mailbox

• mdio

• memory

• memory-controller

• mmc

• mmc-slot

• mouse

• nand-controller

• nvram

• oscillator

• parallel

• pc-card

• pci

• pcie

• phy

• pinctrl

• pmic

• pmu

• port

• ports

• power-monitor

• pwm

• regulator

• reset-controller

• rng

• rtc

• sata

• scsi

• serial

• sound

• spi

• sram-controller

• ssi-controller

• syscon

• temperature-sensor

• timer

• touchscreen

• tpm

• usb

• usb-hub

• usb-phy

• video-codec

• vme

• watchdog

• wifi

2.2.3 路径名称 Path Names

设备树中的节点,其完整路径是从根节点开始,经过所有的下级节点,到达此节点。使用完整路径可以唯一的识别一个设备树中的节点。

指定一个设备路径的惯例是:

/node-name-1/node-name-2/node-name-N

例如,在图2.2中,到cpu #1的设备路径是:

/cpus/cpu@1

到根节点的路径是/。

如果通往节点的完整路径是明确的,可以省略单元地址unit address。

如果客户程序遇到了一个不明确的路径,它的行为是未定义的。

2.2.4 属性 Properties

设备树中的每个节点都有描述该节点特性的属性。属性由一个名称和 一个值组成。

属性名称 Property Names

属性名是由1到31个字符组成的字符串,这些字符在表2.2中。(属性名称可用的字符)

非标准属性名称应指定一个独特的字符串前缀,如公司简称,来识别用该属性是由该公司或组织定义的名称。例子:

fsl,channel-fifo-len

ibm,ppc-interrupt-server#s

linux,network-index

属性值 Property Values

一个属性值是一个由零个或多个字节组成的数组,包含与该属性相关的信息。

如果表示的是真-假信息,属性可能会有一个空值。在这种情况下,用该属性的存在或不存在来表示。

属性的存在或不存在都是充分的描述性的。

表2.3描述了由DTSpec定义的一组基本值类型。

2.3 标准属性 Standard Properties

DTSpec为设备节点指定了一组标准属性。这些属性将在本节中详细描述。

由DTSpec定义的设备节点(见第3章)可以指定关于使用标准属性的额外要求或约束。第4章描述了特定设备的表示方法,也可能指定额外的要求。

注意:本文件中所有的devicetree节点的例子都使用DTS(Devicetree Source)格式来指定节点和属性。

2.3.1 兼容 compatible

属性名称:compatible

值类型: <stringlist>。

说明:

compatible属性的值由一个或多个字符串组成,这些字符串定义了设备的特定编程模型。这个字符串列表应该被客户程序用来选择设备驱动程序。该属性值由一个空尾字符串的连接起来的列表组成,从最具体到最一般。它们允许将一个设备的兼容性表达为一系列类似设备,这样就有可能允许一个设备驱动程序与多个设备相匹配。

推荐的格式是"manufacturer,model",其中manufacturer是一个描述制造商名称的字符串(如公司简称),而model则指定了模型号码。

表示兼容属性的字符串值应该只由小写字母、数字和破折号组成,并且应该以字母开头。单个逗号通常只在供应商前缀之后使用。不应使用下划线。

例如:

compatible = "fsl,mpc8641", "ns16550";

在这个例子中,操作系统会首先尝试找到一个支持fsl,mpc8641的设备驱动程序。如果没有找到 驱动程序,它就会试图找到一个支持更普遍的ns16550设备类型的驱动程序。

2.3.2 模型 model

属性名称:model

值类型: <string>

说明:

model属性值是一个<string>,它指定了设备的制造商型号。

推荐的格式是"manufacturer,model",其中manufacturer是一个描述制造商名称的字符串(如公司简称),而model则指定型号。

例如:

model = "fsl,MPC8349EMITX";

2.3.3 句柄 phandle

属性名称:phandle

值类型: <u32>

说明:

phandle属性为一个节点指定了一个数字标识符,该标识符在设备树内是唯一的。phandle属性值可以被其他节点使用,用来引用其相关的节点。

例如:

见以下devicetree摘录:

pic@10000000 {

    phandle = <1>;

    interrupt-controller;

    reg = <0x10000000 0x100>;

};

一个phandle被定义,值为1。另一个设备节点可以通过值为1的phandle来引用这个pic节点。

another-device-node {

    interrupt-parent = <1>;

};

注意:可能会遇到旧版本的devicetrees,它包含这个属性的一个过时的形式,叫做linux,phandle。为了兼容,如果没有phandle属性,客户程序可能希望支持linux,phandle。这两个属性的含义和用途是相同的。

注意:DTS中的大多数设备树(见附录A)将不包含明确的phandle属性。当DTS被编译成二进制DTB格式时,DTC工具会自动插入phandle属性。

2.3.4 状态 status

属性名称:status

值类型: <string>

说明:

状态属性指示了设备的运行状态。缺少状态属性应被视为该属性存在,其值为 "okay"。有效值在表 2.4 中列出并定义。

2.3.5 单元地址和大小 #address-cells and #size-cells

属性名称:#address-cells, #size-cells

值类型: <u32>

说明:

#address-cells和#size-cells属性可用于任何在devicetree层次结构中拥有子节点的设备节点,并描述应如何对子设备节点进行寻址。#address-cells属性定义了用于编码子节点的reg属性中的地址字段的<u32>单元的数量。#size-cells属性定义了用于编码子节点的reg属性中的大小字段的<u32>单元的数量。

#address-cell和#size-cells属性不从devicetree中的祖先继承。它们应被明确定义。

符合DTSpec的启动程序应在所有的有子节点的节点上提供#address-cell和#size-cells。

如果缺省,客户程序应该假定#address-cell的默认值为2,#size-cells的值为1。

例如:

见以下devicetree摘录:

soc {

    #address-cells = <1>;

    #size-cells = <1>;

    serial@4600 {

        compatible = "ns16550";

        reg = <0x4600 0x100>;

        clock-frequency = <0>;

        interrupts = <0xA 0x8>;

        interrupt-parent = <&ipic>;

    };

};

在这个例子里,soc节点的#address-cells格和#size-cells属性都被设置为1。这个设置指定了需要一个单元来代表地址,需要一个单元来代表作为这个节点的子节点的大小。

串行设备reg属性必然遵循父节点(soc)中设置的这种规范--地址由一个单元(0x4600)表示,大小由一个单元格(0x100)表示。

2.3.6 寄存器 reg

属性名称:reg

值类型: <prop-encoded-array>被编码为一个任意数量的(地址,长度)对。

说明:

reg 属性描述了设备的资源在其父总线所定义的地址空间内的地址。最常见的意义是内存映射的IO寄存器块的偏移量和长度,但在某些总线类型上可能有不同的含义。根节点定义的地址空间中的地址是CPU可访问的实际地址。

该值是一个<prop-encoded-array>,由任意数量的地址和长度对组成。指定地址和长度所需的<u32>单元的数量是由总线而定,由设备节点的父节点中的#address-cell和#size-cells属性指定。如果父节点为#size-cells指定的值是0,那么reg值中的长度字段应被省略。

例如:

假设一个片上系统的设备有两个寄存器块,一个是位于SOC中偏移量0x3000的32字节块,一个是位于偏移量0xFE00的256字节块。寄存器属性将被编码如下(假设#address-cell和#size-cells值为1):

reg = <0x3000 0x20 0xFE00 0x100>;

2.3.7 虚拟寄存器 virtual-reg

属性名称:virtual-reg

值类型: <u32>

说明:

virtual-reg 属性指定了一个有效地址,该地址映射到设备节点的 reg 属性中指定的第一个物理地址。这个属性使启动程序能够向客户程序提供已经设置好的虚拟到物理的映射关系。

2.3.8 范围 ranges

属性名称:ranges

值类型: <empty>或 <prop-encoded-array> , 数组形式的编码为任意数量的(child-bus-address, parent-bus-address, length)的三联体。

说明:

ranges属性提供了一种方法,用于定义总线的地址空间(子地址空间)和总线节点的父地址空间(父地址空间)之间的映射或转换。

ranges属性的值的格式是一个任意数量的(子总线地址,父总线地址,长度)的三联体。

 - 子总线地址是子总线地址空间内的一个物理地址。表示该地址的单元数量与总线有关,可以从该节点(范围属性出现的节点)的#address-cell中确定。

 - 父总线地址是父总线地址空间内的一个物理地址。表示父级地址的单元数量与总线有关,可以从定义父级地址空间的节点的#address-cell属性中确定。

 - 长度指定了子节点地址空间中的范围大小。表示大小的单元的数量可以从这个节点(范围属性出现的节点)的#size-cells中确定。

如果该属性被定义为<empty>值,它指定父子地址空间是相同的,不需要进行地址转换。

如果该属性没有出现在总线节点中,则假定该节点的子节点和父节点的地址空间之间不存在映射。

地址转换实例:

soc {

    compatible = "simple-bus";

    #address-cells = <1>;

    #size-cells = <1>;

    ranges = <0x0 0xe0000000 0x00100000>;

    serial@4600 {

        device_type = "serial";

        compatible = "ns16550";

        reg = <0x4600 0x100>;

        clock-frequency = <0>;

        interrupts = <0xA 0x8>;

        interrupt-parent = <&ipic>;

    };

};

soc节点指定一个ranges属性为:

<0x0 0xe0000000 0x00100000>;

这个属性值规定,对于1024KB的地址空间范围,一个在物理0x0处寻址的子节点映射到物理0xe0000000的父地址。通过这种映射,串行设备节点可以通过加载或存储在地址0xe0004600、0x4600的偏移量(在reg中指定)加上范围中指定的0xe0000000的映射来寻址。

2.3.9 dma范围  dma-ranges

属性名称:dma-ranges

值类型: <empty>或 <prop-encoded-array> , 数组形式的编码为任意数量的(child-bus-address, parent-bus-address, length)的三联体。

说明:

dma-ranges属性用于描述内存映射总线的直接内存访问(DMA)结构,该总线的devicetree父节点可被源自该总线的DMA操作访问。它提供了一种方法来定义总线的物理地址空间和总线的父级物理地址空间之间的映射或转换。

dma-ranges属性的值的格式是一个任意数量的(子总线地址,父总线地址,长度)的三联体。指定的每个三联体描述了一个连续的DMA地址范围。

- 子总线地址是子总线地址空间内的一个物理地址。表示该地址的单元数量取决于总线,可以从该节点(dma-ranges属性出现的节点)的#address-cell中确定。

- 父总线地址是父总线地址空间内的一个物理地址。表示父总线地址的单元数量与总线有关,可以从定义父节点地址空间的的#address-cell属性中确定。

- 长度指定了子节点地址空间中的范围大小。表示大小的单元的数量可以从这个节点(dma-ranges属性出现的节点)的#size-cells中确定。

2.3.10 dma范围  dma-coherent

属性名称:dma-coherent

值类型: <empty>

说明:

对于一些默认不能使用I/O映射的架构,dma-coherent属性用于指示设备能够进行相干的DMA操作。有些架构默认有DMA,则不需要则个属性。

2.3.11 名称  name (dprecated 已不建议使用)

属性名称:name

值类型: <string>

说明:

name属性是一个字符串,指定了节点的名称。这个属性已被废弃,不建议使用。然而,它可能被用于旧的不符合DTSpec的设备树。操作系统应该根据节点名称的node-name组件来确定节点的名称(见第2.2.1节)。

2.3.12 设备类型  device_type (dprecated 已不建议使用)

属性名称:device_type

值类型: <string>

说明:

device_type属性在IEEE 1275中用来描述设备的FCode编程模型。因为DTSpec没有FCode,所以该属性的新用途已被废弃,它应该只包含在cpu和内存节点上,以便与IEEE 1275衍生的devicetrees兼容。