1.设备节点结构体
节点的结构体device_node
49 struct device_node {
50 const char *name;
51 const char *type;
52 phandle phandle;
53 const char *full_name;
54 struct fwnode_handle fwnode;
55
56 struct property *properties;
57 struct property *deadprops; /* removed properties */
58 struct device_node *parent;
59 struct device_node *child;
60 struct device_node *sibling;
61 struct kobject kobj;
62 unsigned long _flags;
63 void *data;
64 #if defined(CONFIG_SPARC)
65 const char *path_component_name;
66 unsigned int unique_id;
67 struct of_irq_controller *irq_trans;
68 #endif
69 };
2. 属性property
35 struct property {
36 char *name;
37 int length;
38 void *value;
39 struct property *next;
40 unsigned long _flags;
41 unsigned int unique_id;
42 struct bin_attribute attr;
43 };
举例:
160 gic: [email protected] {
161 compatible = "arm,cortex-a9-gic";
162 #interrupt-cells = <3>;
163 #address-cells = <0>;
164 interrupt-controller;
165 reg = <0x1e001000 0x1000>,
166 <0x1e000100 0x100>;
167 };
解析:
device_node->name = "interrupt-controller"
device_node->full_name = "/[email protected]"
节点中的每一组数据( compatible = "arm,cortex-a9-gic")通过结构体property表示,property->next指向另外一组数据。
device_node->property->name="compatible "
device_node->property->value="arm,cortex-a9-gic "
device_node->property->length=16 //字符串长度
device_node->property->next->name="reg "
device_node->property->next->value={0x1e,0x0,0x10,0x0, 0x0,0x0,0x,10,0x0 0x1e,0x0,0x01,0x0, 0x0,0x0,0x,01,0x0 }
device_node->property->next->length=4 //每个数值的长度,也就是4个字节代表一个值
1)节点中的每一组数据( compatible = “arm,cortex-a9-gic”)通过结构体property表示
2)property->next指向另外一组数据;这样把一个节点中所有组数据串联起来
3) property->length如果property->value是字符串,则length是字符串长度;
如果property->value数字,这length表示一个字段占几个字节。
比如
reg = <0x1e001000 0x1000>,
<0x1e000100 0x100>;
device_node->property->next->value={0x1e,0x0,0x10,0x0, 0x0,0x0,0x,10,0x0 0x1e,0x0,0x01,0x0, 0x0,0x0,0x,01,0x0 }
如果length=4,一共16个字节,数据就会变成0x1e001000 0x1000 0x1e000100 0x100和reg配置对应起来
获取REG数值
获取REG的函数是of_address_to_resource:
参数: 1.解析节点 2.REG中的第几组参数 3解析结果保存到res中
829 int of_address_to_resource(struct device_node *dev, int index,
830 struct resource *r)
831 {
832 const __be32 *addrp;
833 u64 size;
834 unsigned int flags;
835 const char *name = NULL;
836
837 addrp = of_get_address(dev, index, &size, &flags);
838 if (addrp == NULL)
839 return -EINVAL;
840
841 /* Get optional "reg-names" property to add a name to a resource */
842 of_property_read_string_index(dev, "reg-names", index, &name);
843
844 return __of_address_to_resource(dev, addrp, size, flags, name, r);
845 }
举例:
reg = <0x1e001000 0x1000>,
<0x1e000100 0x100>;
如果这样调用:
of_address_to_resource(np, 0, &res)
res.start=1e001000
res.end=1e001fff
of_address_to_resource(np, 1, &res)
res.start=1e000100
res.end=1e0001ff
of_iomap
874 void __iomem *of_iomap(struct device_node *np, int index)
875 {
876 struct resource res;
877
878 if (of_address_to_resource(np, index, &res))
879 return NULL;
884
885 return ioremap(res.start, resource_size(&res));
886 }
说明:把reg配置的物理地址转化为虚拟地址。