address-cells 和 size-cells 属性

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>

示例

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>

示例

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. 典型应用场景

  1. 内存映射I/O(MMIO)
    • 描述外设寄存器的基地址和范围。
    • 例如:reg = <0x1000 0x100>; 表示基地址 0x1000,范围 0x100 字节。
  2. 内存区域
    • 描述系统内存的起始地址和大小。
    • 例如:reg = <0x0 0x80000000 0x0 0x20000000>; 表示内存起始地址 0x80000000,大小 0x20000000
  3. 中断控制器
    • 描述中断控制器的寄存器地址。

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 个字段组成(地址范围和长度)。

关键规则

  1. 父节点定义格式:子节点的 reg 属性格式由父节点的 #address-cells 和 #size-cells 决定。
    • reg = <address-cells... size-cells...>
  2. 默认值:若未显式设置,#address-cells 和 #size-cells 默认为 <1>
  3. 兼容性:不同总线类型(如 I2C、SPI、PCI)的典型值需参考具体协议规范。

通过合理设置 #address-cells 和 #size-cells,设备树可以灵活描述硬件拓扑,确保内核正确解析硬件资源。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值