在opensbi和linux kernel中我们看到都会涉及设备树的解析,本文就来分享下设备的一些基本知识。
设备树规格书下载
https://github.com/devicetree-org/devicetree-specification
DTSpec指定了一个称为设备树的构造来描述系统硬件。引导程序将设备树加载到客户端程序的内存中,并将指向设备树的指针传递给客户端。Opensbi中就是通过寄存器a1传递设备树的地址,最终还要传递给linux kernel。
设备树是一种具有描述系统中设备的节点的树数据结构。每个节点都有描述所表示设备特性的属性/值对。除了根节点没有父节点外,每个节点只有一个父节点
节点不应为特定于操作系统或项目的目的而设计。它们应该描述可以由任何操作系统或项目实现的东西
设备树通常用于描述客户端程序不一定能动态检测到的设备。
例如,PCI的架构使客户端能够探测和检测连接的设备,因此可能不需要描述PCI设备的设备树节点。然而,设备节点通常用于描述系统中的PCI主机桥设备
如果探测无法检测到网桥,则此节点是必需的,但在其他情况下是可选的。此外,引导加载程序可以进行PCI探测,并生成一个包含其扫描结果的设备树,以传递给操作系统。
node-name@unit-address
node-name节点名由以下1~31个字符,且只能字母开头。
unit-address单元地址必须与节点的reg属性中指定的第一个地址匹配。如果节点没有reg属性,则必须省略@unit-address,仅使用node-name将该节点与同一级别的其他节点区分开。
根节点没有节点名称或单元地址,由正斜杠(/)标识。
节点名示例,地址无需加0x前缀
节点的名称应该是通用,反映设备的功能,而不是其精确的编程模型。如下是推荐的名称
通过指定从根节点通过所有子节点到所需节点的完整路径,可以唯一标识设备树中的节点。
/node-name-1/node-name-2/node-name-N
例如
/cpus/cpu@1
根节点的路径是/
设备树中的每个节点都有描述节点特性的属性。属性由名称和值组成。
属性名:
由以下1~31个字符组成
非标准属性名称应指定一个唯一的字符串前缀,用于标识定义该属性的公司或组织的名称。示例:
fsl,channel-fifo-len
ibm,ppc-interrupt-server#s
linux,network-index
属性值:
属性值是包含与属性关联信息的0或多个字节的数组。如果表示真假,属性可能为空值,此时属性存在或不存在应该具有足够的信息来确认。
以下是标准值类型
值 | 描述 |
值为空。当属性是否存在有其他足够信息确认时,用于表示真假信息。 | |
大端序格式的32位整数。 | |
表示大端格式的64位整数。由两个 比如0x1122334455667788表示为<0x11223344 0x55667788>. | |
字符串是可打印的,以null结尾。比如”hello”占用6个字节。 address 68 'h' address+1 65 'e' address+2 6C 'l' address+3 6C 'l' address+4 6F 'o' address+5 00 '\0' | |
格式特定于属性。参见属性定义。 | |
连接在一起的 address 68 'h' address+1 65 'e' address+2 6C 'l' address+3 6C 'l' address+4 6F 'o' address+5 00 '\0' address+6 77 'w' address+7 6f 'o' address+8 72 'r' address+9 6C 'l' address+10 64 'd' address+11 00 '\0' |
设备树有一个根节点/
根节点下只能有一个/cpus 节点,至少一个/memory节点。
根节点属性
属性名 | 使用 | 值类型 | 说明 |
#address-cells | R | 指定根节点的子节点reg属性表示address需要的 | |
#size-cells | R | 指定根节点的子节点reg属性表示size 需要的 | |
model | R | 指定唯一标识系统板型号的字符串。建议格式为“制造商,型号” | |
compatible | R | 指定与此平台兼容的平台体系结构列表。操作系统可以在选择特定于平台的代码时使用此属性。建议形式为:"manufacturer,model" | |
serial-number | O | 指定表示设备序列号的字符串。 | |
chassis-type | OR | 指定标识系统形状因子的字符串。属性值可以是以下值之一: • "desktop" • "laptop" • "convertible" • "server" • "tablet" • "handset" • "watch" • "embedded" | |
R=Required, O=Optional, OR=Optional but Recommended, SD=See Definition |
其他标准属性可选
设备树可能有一个别名节点(/aliases),用于定义一个或多个别名属性。别名节点应位于设备树的根节点。属性名指定别名。属性值指定设备树中节点的完整路径。
别名只能是1~31个如下字符,小写
别名值是一个设备路径,编码为字符串。该值表示节点的完整路径,但路径不需要引用叶子节点。
客户端程序可以使用别名属性名称来引用完整的设备路径作为其字符串值的全部或部分。当客户端程序将字符串视为设备路径时,应检测并使用别名
示例
serial0 = "/simple-bus@fe000000/serial@llc500"
aliases {
serial0 = "/simple-bus@fe000000/serial@llc500";
ethernet0 = "/simple-bus@fe000000/ethernet@31c000";
};
所有设备树都需要一个内存设备节点,它描述了系统的物理内存布局。如果系统具有多个内存范围,则可以创建多个内存节点,或者可以在单个内存节点的reg属性中指定这些范围。
当通过[UEFI]引导时,系统内存映射是通过[UEFI]中定义的GetMemoryMap()获得的,如果存在,操作系统必须忽略任何/memory节点
节点属性,其他标准属性可选
属性名 | 使用 | 值类型 | 说明 |
device_type | R | 必须是“memory” | |
reg | R | 由任意数量的address和size对组成,指定内存范围的物理地址和大小 | |
initial-mapped-area | O | 指定初始映射区域的地址和大小。初始映射区域是一个由三元组(有效地址、物理地址、大小)组成的数组。有效地址和物理地址均应为64位( | |
hotpluggable | O | 向操作系统明确提示以后可能会移除此内存。 | |
R=Required, O=Optional, OR=Optional but Recommended, SD=See Definition |
示例
假设
#address-cells = <2>
#size-cells = <2>
memory@0 {
device_type = "memory";
reg = <0x000000000 0x00000000 0x00000000 0x80000000
0x000000001 0x00000000 0x00000001 0x00000000>;
};
memory@0 {
device_type = "memory";
reg = <0x000000000 0x00000000 0x00000000 0x80000000>;
};
memory@100000000 {
device_type = "memory";
reg = <0x000000001 0x00000000 0x00000001 0x00000000>;
};
操作系统将保留内存排除在正常使用之外。这种存储区域通常是为各种设备驱动程序的特殊用途而设计的。
/reserved-memory父节点
#address-cells和#size-cells应使用与根节点相同的值,范围应为空,以便地址转换逻辑正常工作
属性名 | 使用 | 值类型 | 说明 |
#address-cells | R | 指定 | |
#size-cells | R | 指定 | |
ranges | R | 此属性表示父地址到子地址空间之间的映射,见标准属性ranges | |
R=Required, O=Optional, OR=Optional but Recommended, SD=See Definition |
/reserved-memory/子节点
保留内存节点的每个子节点指定一个或多个保留内存区域。每个子节点可以使用reg属性指定特定范围的保留内存,也可以使用具有可选约束的size属性请求动态分配的内存块
按照通用名称推荐的做法,节点名称应反映节点的用途(即“framebuffer ”或“dma-pool”)。如果节点是静态分配,则应在名称后附加单元地址(@
保留内存节点需要reg属性用于静态分配,或需要size属性用于动态分配。动态分配可以使用对齐和分配范围属性来约束内存的分配位置。如果reg和size都存在,则该区域被视为静态分配,reg属性优先,size被忽略。
节点属性,其他标准属性可选
属性名 | 使用 | 值类型 | 说明 |
reg | O | 由任意数量的地址和大小对组成,用于指定内存范围的物理地址和大小。 | |
size | O | 为动态分配的区域保留的内存大小(以字节为单位)。此属性的大小基于父节点的#size-cells。 | |
alignment | O | 地址边界用于对齐分配。此属性的大小基于父节点的#size-cells属性。 | |
alloc-ranges | O | 指定可从中分配的内存区域。格式是与reg属性格式相同的(地址、长度对)元组。 | |
compatible | O | 可能包含以下字符串: shared-dma-pool 厂商指定的字符串 | |
no-map | O | 如果存在,则表示操作系统不得创建该区域的虚拟映射作为其系统内存标准映射的一部分,也不得允许在除使用该区域的设备驱动程序控制之外的任何情况下对其进行推测性访问。 | |
reusable | O | 操作系统可以使用此区域中的内存,但受限于拥有该区域的设备驱动程序需要能够将其回收。通常,这意味着操作系统可以使用该区域存储易失性或缓存的数据,这些数据可以以其他方式重新生成或迁移到其他地方。 | |
R=Required, O=Optional, OR=Optional but Recommended, SD=See Definition |
no-map 和 reusable 属性是互斥的,不能在同一节点中同时使用。Linux实施说明:
如果存在linux,cma-default默认属性,则linux将使用该区域作为连续内存分配器的默认池。
如果存在linux,dma-default默认属性,则linux将使用该区域作为一致dma分配器的默认池
设备节点引用保留内存
通过向设备节点添加内存区域属性,其他设备节点可以引用/保留内存节点中的区域。
属性名 | 使用 | 值类型 | 说明 |
memory-region | O | phandle, specifier指向 子/reserved-memory | |
memory-region-names | O | 名称列表,内存区域属性中的每个对应条目对应一个名称 | |
R=Required, O=Optional, OR=Optional but Recommended, SD=See Definition |
当通过[UEFI]引导时,静态/保留内存区域也必须列在通过[UEFI]中定义的GetMemoryMap()获得的系统内存映射中。保留的内存区域需要包含在UEFI内存映射中,以防止UEFI应用程序的分配。
具有无映射属性的保留区域必须在EfiReservedMemoryType类型的内存映射中列出。所有其他保留区域必须以EfiBootServicesData类型列出。
动态保留内存区域不得列在[UEFI]内存映射中,因为它们是在退出固件引导服务后由操作系统分配的
示例
此示例为Linux内核定义了3个连续的区域:一个是所有设备驱动程序的默认区域(大小分别为Linux、cma和64MiB),另一个是专用于帧缓冲区设备的区域(名为framebuffer@78000000,8MiB),一个用于多媒体处理(命名为multimedia@77000000,640MB)
/ {
#address-cells = <1>;
#size-cells = <1>;
memory {
reg = <0x40000000 0x40000000>;
};
reserved-memory {
#address-cells = <1>;
#size-cells = <1>;
ranges;
/* global autoconfigured region for contiguous allocations */
linux,cma {
compatible = "shared-dma-pool";
reusable;
size = <0x4000000>;
alignment = <0x2000>;
linux,cma-default;
};
display_reserved: framebuffer@78000000 {
reg = <0x78000000 0x800000>;
};
multimedia_reserved: multimedia@77000000 {
compatible = "acme,multimedia-memory";
reg = <0x77000000 0x4000000>;
};
};
/* ... */
fb0: video@12300000 {
memory-region = <&display_reserved>;
/* ... */
};
scaler: scaler@12500000 {
memory-region = <&multimedia_reserved>;
/* ... */
};
codec: codec@12600000 {
memory-region = <&multimedia_reserved>;
/* ... */
};
}
/chosen节点不代表系统中的真实设备,而是描述了系统固件在运行时选择或指定的参数。它应该是根节点的子节点。
其中bootargs属性用于传递参数给内核,最常使用。
属性名 | 使用 | 值类型 | 说明 |
bootargs | O | 一个字符串,指定客户端程序的启动参数。如果不需要启动参数,则该值可能是空字符串。 | |
stdout-path 老版本是linux,stdout-path | O | 一个字符串,指定表示用于引导控制台输出的设备的节点的完整路径。如果值中存在字符“:”,则终止路径。该值可能是别名。如果未指定stdin路径属性,则应假定stdout路径来定义输入设备。 | |
stdin-path | O | 一个字符串,指定表示用于引导控制台输入的设备的节点的完整路径。如果值中存在字符“:”,则终止路径。该值可能是别名。 | |
R=Required, O=Optional, OR=Optional but Recommended, SD=See Definition |
示例
chosen {
bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200";
};
所有设备树都需要有一个/cpus节点。它并不代表系统中的真实设备,而是作为代表系统cpu的子cpu节点的容器。
属性名 | 使用 | 值类型 | 说明 |
#address-cells | R | 指定 | |
#size-cells | R | 指定 | |
R=Required, O=Optional, OR=Optional but Recommended, SD=See Definition |
cpu节点表示一个硬件执行块,它足够独立,能够运行操作系统,而不会干扰可能运行其他操作系统的其他cpu
共享MMU的硬件线程通常在一个cpu节点下表示。如果设计了其他更复杂的CPU拓扑结构,CPU的绑定必须描述拓扑结构(例如,不共享MMU的线程)
CPU和线程通过统一的编号空间进行编号,该编号空间应尽可能与中断控制器的CPU/线程编号相匹配
跨cpu节点具有相同值的属性可以放置在/cpus节点中。客户端程序必须首先检查特定的cpu节点,但如果找不到预期的属性,则应查看父/cpus节点。这使得所有CPU上相同的属性表示不那么冗长。
每个CPU节点的节点名称应该是cpu
一般属性
老版本中clock-frequency是bus-frequency
属性名 | 使用 | 值类型 | 说明 |
device_type | R | 必须是"cpu" | |
reg | R | array | |
clock-frequency | O | array | 指定CPU的时钟速度,单位为赫兹(如果恒定)。 U32或者u64格式 |
timebase-frequency | O | array | 指定时基和递减器寄存器更新的当前频率(赫兹)。 U32或者u64格式 |
status | SD | "okay" :cpu在运行 "disabled" cpu 禁止 "fail"cpu未运行或不存在
| |
enable-method | SD | "spin-table" : "[vendor],[method]" | |
cpu-release-addr | SD | enable-method=spin-table时使用 该值指定了从其旋转循环中释放辅助CPU的旋转表条目的物理地址。 | |
R=Required, O=Optional, OR=Optional but Recommended, SD=See Definition |
属性名 | 使用 | 值类型 | 说明 |
power-isa-version | O | 指定Power ISA版本字符串的数字部分的字符串。 | |
power-isa-* | O | ||
cache-op-block-size | SD | 指定缓存块指令操作的块大小(以字节为单位)(例如dcbz)。如果与L1缓存块大小不同,则为必填项。 | |
reservation-granule-siz | SD | 指定此处理器支持的保留粒度大小(以字节为单位)。 | |
mmu-type | O | MMU类型 • "mpc8xx" • "ppc40x" • "ppc440" • "ppc476" • "power-embedded" • "powerpc-classic" • "power-server-stab" • "power-server-slb" • "none" | |
enable-method | SD | "spin-table" : "[vendor],[method]" | |
cpu-release-addr | SD | enable-method=spin-table时使用 该值指定了从其旋转循环中释放辅助CPU的旋转表条目的物理地址。 | |
R=Required, O=Optional, OR=Optional but Recommended, SD=See Definition |
TLB属性
cpu节点的以下属性描述了处理器MMU中的转换备用缓冲区。
属性名 | 使用 | 值类型 | 说明 |
tlb-split | SD | 如果存在,则指定TLB具有拆分配置,指令和数据具有单独的TLB。如果不存在,则指定TLB具有统一的配置。在拆分配置中具有TLB的CPU需要此项。 | |
tlb-size | SD | 指定TLB中的条目数。具有统一TLB的CPU需要指令和数据地址。 | |
tlb-sets | SD | 指定TLB中关联性集的数量。具有统一TLB的CPU需要指令和数据地址 | |
d-tlb-size | SD | 指定数据TLB中的条目数。具有拆分TLB配置的CPU需要 | |
d-tlb-sets | SD | 指定数据TLB中的关联性集的数量。具有拆分TLB配置的CPU需要 | |
i-tlb-size | SD | 指定指令TLB中的条目数。具有拆分TLB配置的CPU需要 | |
i-tlb-sets | SD | 指定指令TLB中的关联性集的数量。具有拆分TLB配置的CPU需要。 | |
R=Required, O=Optional, OR=Optional but Recommended, SD=See Definition |
Internal (L1) Cache属性
next-level-cache在老版本叫l2-cache
属性名 | 使用 | 值类型 | 说明 |
cache-unified | SD | 如果存在,则指定缓存具有统一的组织。如果不存在,则指定缓存具有哈佛架构,其中包含用于指令和数据的单独缓存 | |
cache-size | SD | 指定统一缓存的大小(以字节为单位)。如果缓存是统一的(指令和数据组合),则需要 | |
cache-sets | SD | 指定统一缓存中关联性集的数量。如果缓存是统一的(指令和数据组合),则需要 | |
cache-block-size | SD | 指定统一缓存的块大小(以字节为单位)。如果处理器具有统一缓存(指令和数据组合),则需要 | |
cache-line-size | SD | 指定统一缓存的行大小(以字节为单位),如果与处理器具有统一缓存(组合指令和数据)时所需的缓存块大小不同 | |
i-cache-size | SD | 指定指令缓存的大小(以字节为单位)。如果cpu有单独的指令缓存,则需要 | |
i-cache-sets | SD | 指定指令缓存中关联性集的数量。如果cpu有单独的指令缓存,则需要 | |
i-cache-block-size | SD | 指定指令缓存的块大小(以字节为单位)。如果cpu有单独的指令缓存,则需要。 | |
i-cache-line-size | SD | 指定指令缓存的行大小(以字节为单位)(如果不同于缓存块大小)。如果cpu有单独的指令缓存,则需要。 | |
d-cache-size | SD | 指定数据缓存的大小(以字节为单位)。如果cpu有单独的数据缓存,则需要 | |
d-cache-sets | SD | 指定数据缓存中关联性集的数量。如果cpu有单独的数据缓存,则需要。 | |
d-cache-block-size | SD | 指定数据缓存的块大小(以字节为单位)。如果cpu有单独的数据缓存,则需要。 | |
d-cache-line-size | SD | 如果与缓存块大小不同,则指定数据缓存的行大小(以字节为单位)。如果cpu有单独的数据缓存,则需要 | |
next-level-cache | SD | 如果存在,则表示存在另一级缓存。该值是下一级缓存的phandle。 | |
R=Required, O=Optional, OR=Optional but Recommended, SD=See Definition |
示例
cpus {
cpu@0 {
device_type = "cpu";
reg = <0>;
d-cache-block-size = <32>; // L1 - 32 bytes
i-cache-block-size = <32>; // L1 - 32 bytes
d-cache-size = <0x8000>; // L1, 32K
i-cache-size = <0x8000>; // L1, 32K
timebase-frequency = <82500000>; // 82.5 MHz
clock-frequency = <825000000>; // 825 MHz
};
};
处理器和系统可以实现额外级别的缓存层次结构。例如,第二级(L2)或第三级(L3)缓存。这些缓存可以紧密集成到CPU中,也可以在多个CPU之间共享
具有兼容值“cache”的设备节点描述了这些类型的缓存。
缓存节点应定义phandle属性,与缓存关联或共享缓存的所有cpu节点或缓存节点都应包含一个下一级缓存属性,该属性将phandle指定给缓存节点。
缓存节点可以在CPU节点或设备树中的任何其他适当位置下表示
属性名 | 使用 | 值类型 | 说明 |
compatible | R | 标准属性。该值应包括字符串“cache”。。 | |
cache-level | R | 指定缓存层次结构中的级别。例如,2级缓存的值为2 | |
R=Required, O=Optional, OR=Optional but Recommended, SD=See Definition |
示例
两个CPU,每个CPU都有自己的片上L2和共享L3
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
device_type = "cpu";
reg = <0>;
cache-unified;
cache-size = <0x8000>; // L1, 32 KB
cache-block-size = <32>;
timebase-frequency = <82500000>; // 82.5 MHz
next-level-cache = <&L2_0>; // phandle to L2
L2_0:l2-cache {
compatible = "cache";
cache-unified;
cache-size = <0x40000>; // 256 KB
cache-sets = <1024>;
cache-block-size = <32>;
cache-level = <2>;
next-level-cache = <&L3>; // phandle to L3
L3:l3-cache {
compatible = "cache";
cache-unified;
cache-size = <0x40000>; // 256 KB
cache-sets = <0x400>; // 1024
cache-block-size = <32>;
cache-level = <3>;
};
};
};
cpu@1 {
device_type = "cpu";
reg = <1>;
cache-unified;
cache-block-size = <32>;
cache-size = <0x8000>; // L1, 32 KB
timebase-frequency = <82500000>; // 82.5 MHz
clock-frequency = <825000000>; // 825 MHz
next-level-cache = <&L2_1>; // phandle to L2
L2_1:l2-cache {
compatible = "cache";
cache-unified;
cache-level = <2>;
cache-size = <0x40000>; // 256 KB
cache-sets = <0x400>; // 1024
cache-line-size = <32>; // 32 bytes
next-level-cache = <&L3>; // phandle to L3
};
};
};
属性名: compatible
值类型:
兼容compatible属性值由一个或多个字符串组成(字符串以\0结尾),多个字符串按一般到具体的顺序组织,这些字符串定义了设备的特定编程模型,用于表达一系列类似设备的兼容性,可能一个设备驱动程序兼容多个设备。
使用此字符串列表来选择设备驱动程序。
我们前面opensbi和linux代码中就大量看到了使用compatible来进行匹配。
推荐“制造商,型号”的描述方式。
字符串应仅由小写字母、数字和破折号组成,并且应以字母开头。单个逗号通常仅在供应商前缀后使用。不应使用下划线。
示例:
compatible = "fsl,mpc8641", "ns16550";
在这个例子中,操作系统将首先尝试定位支持fsl的设备驱动程序mpc8641。如果找不到驱动程序,它将尝试查找支持更通用的ns16550设备类型的驱动程序。即按照一般到具体的描述组织。
属性名: model
值类型:
model属性值是一个
示例
model = "fsl,MPC8349EMITX";
属性名: phandle
值类型:
phandle属性为设备树中具备唯一性的节点指定数字标识符。phandle属性值由需要引用该节点的其他节点使用。
示例:
节点pic定义了phandle=1的标志,这样another-device-node可以通过1找到pic节点。
pic@10000000 {
phandle = <1>;
interrupt-controller;
reg = <0x10000000 0x100>;
}
another-device-node {
interrupt-parent = <1>;
}
注老版本属性名是linux,phandle. 如果要兼容则先看是否是phandle然后再看是不是linux,phandle.
DTS中的大多数设备树不包含显式的phandle属性。当DTS编译为二进制DTB格式时,DTC工具会自动插入phandle属性。
属性名: status
值类型:
status属性表示设备的运行状态。如果没有该属性则默认认为是”okay”。
值有如下
值 | 描述 |
“okay” | 表示设备是运行的 |
"disabled" | 表示设备当前未运行,但将来可能会运行(例如,某些设备未插入或关闭)。 |
"reserved" | 表示设备可以运行,但不应使用。通常,这用于由另一个软件组件(如平台固件)控制的设备 |
"fail" | 表示设备无法运行。在设备中检测到严重错误,如果不进行维修,它不太可能运行。 |
"fail-sss" | 表示设备无法运行。在设备中检测到严重错误,如果不进行维修,设备不太可能运行。该值的sss部分特定于设备,表示检测到的错误情况。 |
属性名: #address-cells, #size-cells
值类型:
可以在设备树层次结构中具有子节点的任何节点中使用,并描述了应如何寻址子设备节点。
#address-cells属性定义了以多少个
#size-cells属性定义了以多少个
#address-cells和#size-cells不是从设备树中的祖先继承的,所以要在所有拥有子节点的节点处明确指定,不指定则dtc编译时会告警。
程序解析时如果没找到这个属性则默认认为 #address-cells为2,#size-cells为1.
示例
#address-cells 和 #size-cells都是1,所以子节点serial中的reg属性,0x4600表示地址,0x100表示大小。
soc {
#address-cells = <1>;
#size-cells = <1>;
serial@4600 {
compatible = "ns16550";
reg = <0x4600 0x100>;
clock-frequency = <0>;
interrupts = <0xA 0x8>;
interrupt-parent = <&ipic>;
};
}
属性名: reg
值类型:
reg属性描述了设备资源在其父总线定义的地址空间内的地址。最常见的是内存映射IO寄存器块的偏移量和长度,但在某些总线类型上可能有不同的含义。根节点定义的地址空间中的地址是CPU实际地址。
其中address和length由多少个
如果#size-cells为0则表示没有length,只有address.
示例
假设父节点
#address-cells和#size-cells values 都是1
则以下表示偏移0x3000处的0x20字节区域,和偏移0xFE00处的0x100字节区域。
reg = <0x3000 0x20 0xFE00 0x100>;
属性名: virtual-reg
值类型:
指定了一个有效地址,该地址映射到由reg属性指定的第一个物理地址。此属性使引导程序能够为客户端程序提供已设置的虚拟到物理映射。
属性名: ranges
值类型:
range属性提供了一种定义总线地址空间(子地址空间)和总线节点父节点地址空间(父地址空间)之间映射或转换的方法。该属性定义在父节点。
child-bus-address是子总线地址空间内的物理地址。地址的单元数取决于ranges所在节点下的#address-cells属性的指定。
parent-busaddress是父总线地址空间内的物理地址。地址的单元数取决于ranges所在节点的父节点下的#address-cells属性的指定。
length指定了子地址空间中范围的大小。大小的单元数取决于ranges所在节点下的#address-cells属性的指定。
如果属性定义为
如果总线节点中不存在该属性,则假定节点的子节点和父地址空间之间不存在映射。
示例
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>;
对于1MB的地址空间范围,在物理0x0处寻址的子节点映射到物理0xe0000000的父地址。通过此映射,serial节点可以通过地址0xe0004600来寻址,偏移量为0x4600(在reg中指定)加上范围中指定的0xe0000000映射。
属性名: dma-ranges
值类型:
dma-ranges用于描述内存映射总线的(dma)结构,该总线的设备树父节点可以通过源自总线的dma操作进行访问。它提供了一种定义总线物理地址空间和总线父级物理地址空间之间的映射或转换的方法。该属性定义在父节点。和ranges类似。
child-bus-address 是子总线地址空间的物理地址, 单元数由dma-ranges所在节点的#address-cells 决定
parent-bus-address 是父总线地址空间的物理地址,单元数由dma-ranges父节点的#address-cells 决定
length指定了子地址空间中范围的大小。单元数由dma-ranges所在节点的#address-cells 决定。
属性名: dma-coherent
值类型:
对于默认I/O non-coherent 的架构,non-coherent用于表示设备支持coherent DMA 操作。某些架构默认是non-coherent DMA ,此属性不适用。
属性名: dma-noncoherent
值类型:
对于默认I/O coherent 的架构,dma-noncoherent用于表示设备不支持coherent DMA 操作。某些架构默认是non-coherent DMA ,此属性不适用。
属性名: name
值类型:
name属性用于指定节点名称。此属性已弃用,不建议使用。它可能用于较旧的不符合DTSpec的设备树。操作系统应根据node-name来确定节点名称。
属性名: device_type
值类型:
device_type属性在IEEE 1275中用于描述设备的FCode编程模型。由于DTSpec没有FCode,因此该属性已被弃用,为了与IEEE 1275衍生的设备树兼容,它应该只包含在cpu和memory节点上。