You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何我的程序从设备树获取的address-cells/size-cells值不符合预期?

libfdt中fdt_address_cells/fdt_size_cells返回父节点值而非-FDT_BAD_NCELLS的问题解析

问题场景

使用libfdt库操作设备树时遇到异常:

  • 设备树里reserved-memory节点定义了#address-cells = <0x02>和#size-cells = <0x02>,其子节点some-block未单独指定这两个属性
  • 调用fdt_address_cells()获取some-block的地址单元数返回0x2,调用fdt_size_cells()返回0x1
  • 根据libfdt.h的函数描述,预期节点未指定对应属性时应返回-FDT_BAD_NCELLS,实际结果与预期不符

对应的设备树代码:

reserved-memory {
        #address-cells = <0x02>;
        #size-cells = <0x02>;
        
       some-block {
            reg = <0x00 0xaa000000 0x00 0xbb00000>;
            no-map;
            compatible = "somevendor,something";
        };
 }

原因解析

你对fdt_address_cells()和fdt_size_cells()的行为存在误解:这两个函数并非仅检查当前节点的属性,而是遵循设备树的属性继承规则——如果当前节点未定义#address-cells或#size-cells,会自动向上递归查找父节点的对应属性,直到找到有效属性或遍历至根节点。只有当整个路径都找不到对应属性时,才会返回-FDT_BAD_NCELLS。

针对你的场景:

  1. some-block未定义#address-cells,因此继承父节点reserved-memory的#address-cells = <0x02>,所以fdt_address_cells()返回0x2是符合函数实际逻辑的,并非错误。
  2. 关于fdt_size_cells()返回0x1的异常,大概率是因为:
    • 实际dtb文件中reserved-memory节点的#size-cells = <0x02>未被正确编译生效
    • 或reserved-memory的父节点(如根节点)定义了#size-cells = <0x1>,且reserved-memory的#size-cells属性存在解析问题,导致函数向上继承了更上层的属性值

验证与排查步骤

  1. 使用fdt_getprop()直接查询some-block节点的#address-cells和#size-cells属性,确认其确实不存在(返回NULL)
  2. 检查reserved-memory节点的对应属性是否在dtb中正确存在:
    const fdt32_t *prop = fdt_getprop(fdt, reserved_memory_nodeoff, "#size-cells", NULL);
    if (prop) {
        printf("#size-cells value: 0x%x\n", fdt32_to_cpu(*prop));
    }
    
  3. 若reserved-memory的#size-cells属性正确,检查libfdt版本是否存在相关bug,尝试升级至稳定版本

内容的提问来源于stack exchange,提问作者bob_vance

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:50:28