实例分析-reg 属性解析(基于ranges属性)
实例1
/{
#address-cells = <0x01>;
#size-cells = <0x01>;
soc {
compatible = "simple-bus";
#address-cells = <0x01>;
#size-cells = <0x01>;
ranges = <0x7e000000 0x3f000000 0x1000000 0x40000000 0x40000000 0x1000>;
dma@7e007000 {
compatible = "brcm,bcm2835-dma";
reg = <0x7e007000 0xf00>;
......
};
}
......
}
实例2
struct resource {
resource_size_t start; // 0x3f007000
resource_size_t end; // 0x3f007eff
const char *name; // dma@7e007000 (reg-names 或者device_node->full_name)
unsigned long flags; // 0x200 IORESOURCE_MEM
unsigned long desc;
struct resource *parent, *sibling, *child;
};
1. of_address_to_resource 整体分析
of_address_to_resource(np, num_reg, &temp_res)
分析:获取节点的reg 属性,生成struct resource
最终填充到platfor_device 结构体的pdev->num_resources和 pdev->resource
核心的三步操作:
1. addrp = of_get_address(dev, index, &size, &flags);
分析: 获取reg 属性的 第index组的信息(addrp:基地址 size: 大小 flags:默认)
2. of_property_read_string_index(dev, "reg-names",index, &name);
分析: 从reg-names 属性中获取index组的名称
3. return __of_address_to_resource(dev, addrp, size, flags, name, r);
分析: 进行地址转换(基于父节点的ranges属性),并存储到struct resource *r 结构体中
第一步: of_get_address
const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
unsigned int *flags)
{
const __be32 *prop;
unsigned int psize;
struct device_node *parent;
struct of_bus *bus;
int onesize, i, na, ns;
/* Get p