在dts文件里,每个大括号{ }代表一个节点,比如根节点里有个大括号,对应一个device_node结构体;
memory也有一个大括号,也对应一个device_node结构体。
节点里面有各种属性,也可能里面还有子节点,所以它们还有一些父子关系。
根节点下的memory、chosen、led等节点是并列关系,兄弟关系。对于父子关系、兄弟关系,在device_node结构体里面肯定有成员来描述这些关系
struct device_node {
const char *name; // 来自节点中的name属性, 如果没有该属性, 则设为"NULL"
const char *type; // 来自节点中的device_type属性, 如果没有该属性, 则设为"NULL"
phandle phandle;
const char *full_name; // 节点的名字, node-name[@unit-address]
struct fwnode_handle fwnode;
struct property *properties; // 节点的属性
struct property *deadprops; /* removed properties */
struct device_node *parent; // 节点的父亲
struct device_node *child; // 节点的孩子(子节点)
struct device_node *sibling; // 节点的兄弟(同级节点)
#if defined(CONFIG_OF_KOBJ)
struct kobject kobj;
#endif
unsigned long _flags;
void *data;
#if defined(CONFIG_SPARC)
const char *path_component_name;
unsigned int unique_id;
struct of_irq_controller *irq_trans;
#endif
};
device_node结构体表示一个节点,property结构体表示节点的具体属性。
properties结构体的定义如下:
```c
struct property {
char *name; // 属性名字, 指向dtb文件中的字符串 例如reg interrupts
int length; // 属性值的长度
void *value; // 属性值, 指向dtb文件中value所在位置, 数据仍以big endian存储
struct property *next;
#if defined(CONFIG_OF_DYNAMIC) || defined(CONFIG_SPARC)
unsigned long _flags;
#endif
#if defined(CONFIG_OF_PROMTREE)
unsigned int unique_id;
#endif
#if defined(CONFIG_OF_KOBJ)
struct bin_attribute attr;
#endif
};
a. 内核函数of_platform_default_populate_init, 遍历device_node树, 生成platform_device
b. 并非所有的device_node都会转换为platform_device只有以下的device_node会转换:
注意:i2c, spi等总线节点会转换为platform_device,但是,spi、i2c下的子节点无论compatilbe是否为: “simple-bus”,“simple- mfd”,“isa”,"arm,amba-bus "都应该交给对应的总线驱动程序来处理而不会被转换为platform_device
举例:
/ {
mytest { //根节点下的子节点并且包含compatile,因此可以转换为platform_device
compatile = "mytest", "simple-bus";
mytest@0 { //该节点不属于根节点的子节点,因此不会转换为platform_device
compatile = "mytest_0";
};
};
i2c { //根节点下的子节点并且包含compatile,因此可以转换为platform_device
compatile = "samsung,i2c";
at24c02 { //不属于根节点的子节点,并且还是i2c的子节点,一般交给i2c驱动转换为i2c_client
compatile = "at24c02";
};
};
spi { //根节点下的子节点并且包含compatile,因此可以转换为platform_device
compatile = "samsung,spi";
flash@0 { //不属于根节点的子节点,并且还是spi的子节点,一般交给spi驱动转换为spi_device
compatible = "winbond,w25q32dw";
spi-max-frequency = <25000000>;
reg = <0>;
};
};
};