1.概要
2.内容
在设备树(Device Tree)中,address-cells
和 size-cells
是两个关键属性,用于定义如何解析子节点中 reg
属性的地址和大小信息。它们是设备树中描述硬件资源(如内存映射I/O、寄存器等)的基础机制。
1. address-cells
属性
- 作用:定义子节点
reg
属性中 地址字段(address field) 占用的单元格(cell)数量。 - 取值范围:整数(通常为 1 或 2,取决于地址宽度)。
- 典型场景:
- 在 32 位系统中,地址通常用 1 个单元格(32 位)表示,因此
address-cells = <1>
。 - 在 64 位系统中,地址可能用 2 个单元格(64 位)表示,因此
address-cells = <2>
。
- 在 32 位系统中,地址通常用 1 个单元格(32 位)表示,因此
示例:
soc {
#address-cells = <2>; // 子节点的 reg 地址字段占 2 个单元格
#size-cells = <1>; // 子节点的 reg 大小字段占 1 个单元格
spi@0,0 {
reg = <0x0 0x1000 0x100>; // 地址 = 0x00001000(2 个单元格),大小 = 0x100(1 个单元格)
};
};
2. size-cells
属性
- 作用:定义子节点
reg
属性中 大小字段(size field) 占用的单元格(cell)数量。 - 取值范围:整数(通常为 1 或 2,取决于地址空间范围)。
- 典型场景:
- 如果地址空间大小用 32 位表示,则
size-cells = <1>
。 - 如果地址空间大小用 64 位表示,则
size-cells = <2>
。
- 如果地址空间大小用 32 位表示,则
示例:
memory@0 {
device_type = "memory";
reg = <0x0 0x80000000 0x0 0x20000000>; // 地址 = 0x0000000080000000(2 个单元格),大小 = 0x0000000020000000(2 个单元格)
};
3. 继承规则
address-cells
和size-cells
是继承属性,子节点会默认使用父节点的值。- 如果子节点需要覆盖父节点的值,可以显式定义自己的
address-cells
和size-cells
。
示例:
soc {
#address-cells = <2>;
#size-cells = <1>;
i2c@1 {
#address-cells = <1>; // 覆盖父节点的 address-cells
#size-cells = <0>; // 覆盖父节点的 size-cells(表示大小字段不存在)
reg = <0x1>; // 地址 = 0x1(1 个单元格),无大小字段
};
};
4. reg
属性的格式
reg
属性的格式为:
reg = <address1 address2 ... size1 size2 ...>;
- 地址字段:由
address-cells
决定单元格数量。 - 大小字段:由
size-cells
决定单元格数量。
示例:
// 父节点设置:address-cells=2, size-cells=1
reg = <0x0 0x1000 0x100>; // 地址 = 0x00001000,大小 = 0x100
5. 典型应用场景
- 内存映射I/O(MMIO):
- 描述外设寄存器的基地址和范围。
- 例如:
reg = <0x1000 0x100>;
表示基地址0x1000
,范围0x100
字节。
- 内存区域:
- 描述系统内存的起始地址和大小。
- 例如:
reg = <0x0 0x80000000 0x0 0x20000000>;
表示内存起始地址0x80000000
,大小0x20000000
。
- 中断控制器:
- 描述中断控制器的寄存器地址。
6. 注意事项
- 一致性:父节点和子节点的
address-cells
/size-cells
必须一致,否则reg
属性解析会出错。 - 单位:设备树中的地址和大小通常以字节为单位,但具体含义由硬件决定。
- 64位地址:在 64 位系统中,地址可能拆分为高 32 位和低 32 位(如
reg = <0x0 0x1000 0x100>;
)。
总结
address-cells
和size-cells
是设备树中描述硬件资源地址和大小的关键属性。- 它们通过定义
reg
属性的单元格数量,确保内核能正确解析硬件资源的布局。 - 正确设置这些属性是设备树兼容性和硬件抽象化的基础。
3.关联链接
4.关联知识
1.应用举例
在设备树(Device Tree)中,address-cells
和 size-cells
是用于描述总线或父节点如何解析子节点地址和大小的关键属性。它们定义了子节点 reg
属性中地址和大小的表示方式。以下是具体应用举例:
1. I2C 总线示例
场景:I2C 总线上的设备通常通过 7 位地址标识,地址范围为 0x00-0x7F
。
i2c@1 {
compatible = "i2c-bus";
reg = <0x1>; // I2C 总线编号为 1
#address-cells = <1>; // 地址用 1 个 32 位单元表示(7 位地址)
#size-cells = <0>; // 不需要大小字段(I2C 设备无大小概念)
eeprom@50 {
compatible = "atmel,24c02";
reg = <0x50>; // 7 位地址 0x50(二进制 01010000)
};
};
解释:
#address-cells = <1>
:子节点地址占 1 个 32 位单元(7 位地址)。#size-cells = <0>
:子节点不需要大小字段(I2C 设备通常无大小属性)。
2. SPI 总线示例
场景:SPI 设备通过片选(Chip Select, CS)标识,地址为 0-3。
spi@0 {
compatible = "spi-bus";
reg = <0>; // SPI 总线编号为 0
#address-cells = <1>; // 地址用 1 个 32 位单元表示(CS 编号)
#size-cells = <0>; // 不需要大小字段
flash@0 {
compatible = "jedec,spi-nor";
reg = <0>; // CS 编号为 0
spi-max-frequency = <50000000>;
};
};
解释:
#address-cells = <1>
:子节点地址占 1 个 32 位单元(CS 编号)。#size-cells = <0>
:SPI 设备通常无大小字段。
3. 内存区域示例
场景:描述系统的物理内存布局。
memory@0 {
device_type = "memory";
reg = <0x0 0x40000000>; // 起始地址 0x0,大小 1GB
#address-cells = <1>; // 地址用 1 个 32 位单元表示
#size-cells = <1>; // 大小用 1 个 32 位单元表示
};
解释:
#address-cells = <1>
:地址占 1 个 32 位单元(32 位地址)。#size-cells = <1>
:大小占 1 个 32 位单元(32 位大小)。
4. 自定义总线(复杂地址)
场景:自定义总线使用 64 位地址和 32 位大小。
custom-bus@1000 {
compatible = "my-custom-bus";
reg = <0x1000>; // 总线基地址
#address-cells = <2>; // 地址用 2 个 32 位单元表示(64 位地址)
#size-cells = <1>; // 大小用 1 个 32 位单元表示
device@12345678 {
compatible = "my-device";
reg = <0x12345678 0x0000ABCD 0x1000>; // 地址为 0x12345678ABCD,大小为 0x1000
};
};
解释:
#address-cells = <2>
:地址占 2 个 32 位单元(64 位地址)。#size-cells = <1>
:大小占 1 个 32 位单元(32 位大小)。
5. PCI 总线示例
场景:PCI 设备需要复杂的地址映射(如 BAR 配置)。
pci@0 {
compatible = "pci-host-ecam-generic";
reg = <0x0 0x10000000>; // PCI 控制器寄存器地址范围
#address-cells = <3>; // 地址用 3 个 32 位单元(Bus, Device, Function)
#size-cells = <2>; // 大小用 2 个 32 位单元(地址范围和长度)
my-pci-device@0,0,0 {
compatible = "my-pci-driver";
reg = <0x0 0x0 0x0 0x0 0x1000 0x0 0x0>; // Bus 0, Device 0, Function 0,地址范围 0x0-0xFFF
};
};
解释:
#address-cells = <3>
:地址由 3 个字段组成(Bus, Device, Function)。#size-cells = <2>
:大小由 2 个字段组成(地址范围和长度)。
关键规则
- 父节点定义格式:子节点的
reg
属性格式由父节点的#address-cells
和#size-cells
决定。reg = <address-cells... size-cells...>
。
- 默认值:若未显式设置,
#address-cells
和#size-cells
默认为<1>
。 - 兼容性:不同总线类型(如 I2C、SPI、PCI)的典型值需参考具体协议规范。
通过合理设置 #address-cells
和 #size-cells
,设备树可以灵活描述硬件拓扑,确保内核正确解析硬件资源。