设备树规格书(Devicetree Specification)
这章节将会描述遵循设备树规格书要求的设备节点的基础集合。
所有设备树必须要有根节点,并且所有设备书应该要有如下的根节点。
- 一个
/cpus
节点 - 至少一个
/memory
节点
设备书有一个唯一的根节点/
,所有其他的设备节点都为其子节点(后代)
表3.1 根节点属性
属性名 | 用法 | 值类型 | 定义 |
---|---|---|---|
#address-cells |
R | <u32> |
指定/ 的子节点中reg 属性中表示地址所需的<u32> 的数量 |
#size-cells |
R | <u32> |
指定/ 的子节点中reg 属性中表示大小所需的<u32> 的数量 |
model |
R | <string> |
指定能唯一标识主板的字符串,推荐的格式是"制造商,型号" |
ompatible |
R | <stringlist> |
指定与这个平台相兼容的体系结构列表。操作系统可以使用此属性选择特定的平台代号。 |
属性值的推荐格式是"制造商,型号" ,例如: compatible = "fsl, mpc8572ds" |
备注:
- R 为要求的,O为可选的,OR为可选但推荐的,SD为根据定义。
- 所有其他标准属性为可选项
一个设备树可能有定义一个或多个别名属性的别名节点(/aliases
)。别名节点必须在设备树的根节点并用/aliases
命名。
/aliases
节点的每个属性都定义一个别名。属性名表示这个别名,属性值表示一个节点在设备树中的属性。例如,属性serial0="/simple-bus@fe000000/serial@11c500"
定义了别名serial0
.
别名必须是下面表3.2中的字符集所组成的小写且长度为1~31的字符串。
表3.2 别名的有效字符
字符 | 描述 |
---|---|
0-9 | 数字 |
a-z | 小写字母 |
- | 破折号 |
别名的值是一个设备的路径。这个值描述了节点的完整路径,而该路径不需要引用叶节点。
一个客户端程序可能要使用一个属性别名去引用完整的设备路径或其字符串值的一部分。当考虑字符串作为设备路径时,客服端程序应该检测并使用别名。
例子
aliases {
serial0 = "/simple-bus@fe000000/serial@llc500";
ethernet0 = "/simple-bus@fe000000/ethernet@31c000";
};
对于别名serial0
,客户端程序能查询/aliases
节点并且确定别名引用的设备路径/simple-bus@fe000000/serial@11c500
.
所有设备树都需要内存设备节点来描述系统的物理内存层。如果系统有多个内存区域/块,可以创建多个内存节点或在rep
属性中指定内存范围。
节点名的unit-name
必须是memory(见2.2.1节)。
客户端程序可以使用它选择的任何存储属性访问任何非保留内存区域。然而,在改变用于访问实际页改变的存储属性之前,客户端程序需要执行架构所要求的一些操作,可能包括刷新cache缓存中的内容到真实的页。引导程序负责保证,WIMG=0b001x
时,客户端程序可以安全的访问所有内存,而不会受存储属性变化的影响。例如:
- 不需要直写
- 非禁止缓存
- 内存一致性
- 防护要求
如果支持VLE存储属性,则VLE=0
。
表3.3 /memory节点属性
属性名 | 用法 | 值类型 | 定义 |
---|---|---|---|
device_type |
R | <string> |
值必须是"memory" |
reg |
R | <prop-encoded-array> |
任意数值组成的地址和大小对(类似键值对)来描述物理地址和内存区域的大小 |
initial-mapped-area |
O | <prop-encoded-array> |
描述最初映射区域的地址和大小。是由(有效地址,物理地址,大小) 形式的三元组所组成的数组。其中有效/物理地址应该是用64位描述,大小用32位值描述 |
注:所有其他标准属性为可选项。(见2.3节)
例子
下面的物理内存布局给出了一个64位的Power系统:
- RAM:开始地址0x0,长度0x80000000(2G)
- RAM:开始地址0x10000000,长度0x100000000 (4G)
假设#address-cells =<2>
和 #size-cells = <2>
,对应的物理节点能够定义如下:
范例1
memory@0 {
device_type = "memory";
reg = < 0x0000000 0x0000000 0x0000000 0x8000000
0x0000001 0x0000000 0x0000001 0x0000000>;
}
范例2
memory@0 {
device_type = "memory";
reg = < 0x0000000 0x0000000 0x0000000 0x8000000>;
}
memory@0x10000000 {
device_type = "memory";
reg = < 0x0000001 0x0000000 0x0000001 0x0000000>;
}
reg
属性定义了两个内存区域的地址和大小。中间跳过了2GB大小的IO区域。注意,#address-cells 和
#size-cells` 的值是2,这表明在内存节点的reg属性中是用两个32位单元来描述地址和长度的。
在系统中/chosen
节点不代表真实的设备,而是描述在运行时由系统固件选择和指定的描述参数。它必须是根节点的字节点。
表3.4 /chosen 节点属性
属性名 | 用法 | 值类型 | 定义 |
---|---|---|---|
bootargs |
O | <string> |
一个描述客户端程序启动参数的字符串。如果为提供启动参数,默认为空字符串。 |
stdout-path |
O | <string> |
一个描述节点对应设备的完整路径字符串,通常为了启动控制台的输出。在值中“:”表示路径的终结符号。它可能是个别名。如果stdin-path 属性没有指定,那么stdout-path 应该定义这输入设备 |
stdin-path |
O | <string> |
同上,描述输入设备 |
例如
chosen {
bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200";
};
老版本设备树可能会遇到不推荐使用的stdout-path
属性的形式,为linux,stdout-path
。为了兼容性,如果stdout-path
属性不存在,客服端程序可能会去支持linux,stdout-path
。这意味着这两个属性是等同的。
所有设备树都要求有/cpus
属性节点。它在系统中不表示真实的设备,而是为系统中cpu子节点的容器。
表3.5 /cpus节点属性
属性名 | 用法 | 值类型 | 定义 |
---|---|---|---|
#address-cells |
R | <u32> |
这值描述了在该节点的子节点中reg 属性数组的每个元素需要多少单元描述 |
#size-cells |
R | <U32> |
值必须是0.在子节点中的reg 属性中没有大小要求 |
/cpus
节点可能包含通用交叉cpu节点。具体细节见3.7节。
例子,参见3.8.1节。
cpu节点表示一个能独立工作的硬件执行块,并能够在不使用其他cpu的情况下运行一个操作系统。
硬件线程共享一个MMU通常表示在一个cpu节点下。如果有其他更复杂的CPU拓扑设计,则对于这CPU的binding必须要描述拓扑关系(例如:线程没有共享一个MMU)
CPU和线程通过统一的数字空间进行编号,该空间应该尽可能的与中断控制器的CPU/线程编号相匹配。
不同cpu节点具有相同值的属性,可以/应该放到/cpus
节点中。客户端程序必须先检查具体的cpu节点,如果没有对应的属性,应该继续在父节点进行查找,这会减少容余的属性表示。
每个CPU节点的名字都应该是cpu
。
下面表格描述了cpu
节点的通用属性。表3.6中描述的一些属性具有的特定细节和标准特性。
表3.6 /cpus/cpu* 节点通用属性
属性名 | 用法 | 值类型 | 定义 |
---|---|---|---|
device_type |
R | <string> |
值应该是cpu |
reg |
R | array | reg 的值是一个<prop-encoded-array> ,通过CPU节点对CPU/threads的表示定义了唯一的ID。 |
如果一个CPU支持的线程不止一个(多个执行流),reg 属性是每个线程对应一个元素的数组。/cpus 节点上的#address-cells 表示了数组的每个元素占多少个单元。软件可以通过reg 的大小除父节点#address-cells 的方式确定线程数量。 |
|||
如果一个CPU/thread能接受外部中断,那么对应reg 属性的值必须是唯一的,以便中断控制器的寻址。当不能接受外部中断时候,reg属性值必须是唯一且在中断控制器寻址范围外 |
|||
如果一个CPU/thread的PIR(中断阻塞/缓存/等待)是可修改的,则客户端程序应该修改PIR去匹配reg 属性的值。如果PIR不能修改并且PIR值是由中断控制器 数字空间/域确定的,CPUs 绑定可定义一个binding-specific 表示PIR的值。 |
|||
clock-frequency |
R | array | 描述CPU以Hz为单位当前的时钟速率。它的值是如下两种之一的<prop-encoded-array> : |
1.一个32位组成的<u32> 描述频率 |
|||
2.64位整数表示的<u64> 描述频率 |
|||
timebase-frequency |
R | array | 表示当前频率是以哪个时基和递减寄存器更新的。值要求及类型同上 |
status |
SD | <string> |
描述CPU状态的标准属性。在对称多处理器(SMP)配置中表示CPU的的结点应该具有此属性。对于CPU结点中值"okay"和"disabled"的含义如下: |
"okay": cpu是运行状态,"disabled": CPU为暂停状态。静止态CPU处于的状态,即不会影响其他CPU也不会受其他CPU运行的影响,除非有显示的方法去使能(见enable-method 属性)。 |
|||
特别的是,运行的CPU发布TLB无效广播不会影响静止态的CPU。例如:静态CPU可能处于循环中,复位状态,并且和系统总线或其他的依赖状态电器隔离。 | |||
enable-method |
SD | <stringlist> |
描述了CPU在静止状态下被使能的方法。当CPU的status 属性为disabled时要求要存在这个属性。属性的值由一个或多个定义释放CPU的方法的字符串组成。如果客户端程序识别到任何方法,可能会使用它。这值应该是下面中的一个: |
"spin-table": CPU用定义在设备树规范中的spin表中的方法来使能。 | |||
"[vendor], [method]": 依赖于实现的字符串来描述CPU从disable状态释放的方法。要求的格式是"[vendor], [method]",vendor是制造商的名字,method是描述制造商特定的机制。例如:"fsl,MPC8572DS" | |||
注:在DTS规格书后续的修订版本中可能会增加其他方法。 | |||
cpu-release-addr |
SD | <u64> |
当CPU有“spin-table”的使能方法属性值,那么需要配置cpu-release-addr 属性。这个属性描述了spin-table 从它的自旋中释放第二个CPU入口的物理地址 |
power-isa-version |
O | <string> |
描述Power ISA版本中的数字部分。如:一个公司用Power ISA的2.06版本, 那么这歌属性对应为2.06 |
power-isa-* |
O | <empty> |
|
cache-op-block-size |
|||
'reservation-granule-size' | |||
mmu-type |
旧版本的DTS可能遇到CPU结点包含bus-frequency
属性。为了兼容一个客户端程序可能想去支持bus-frequency。该值的格式和时钟频率(clock-frequency)的格式相同。最佳实践是在bus结点上使用clock-frequency
属性。