函数调用过程:
start_kernel //init/main.c
setup_arch(&command_line) //arch/arm/kernel/setup.c
arm_memblock_init(mdesc) //arch/arm/kernel/setup.c
early_init_fdt_reserve_self();
//把dtb所占用区域保留下来,即调用:memblock_reserve
early_init_dt_reserve_memory_arch(__pa(initial_boot_params),fdt_totalsize(initial_boot_params),0)
early_init_fdt_scan_reserved_mem(); //根据dtb中的memreserve信息,调用memblock_reserve
unflatten_device_tree(); //arch/arm/kernel/setup.c
//第一通道,扫描大小
size = unflatten_dt_nodes(blob,NULL,dad,NULL);
//第二通道,将扁平组织展开
unflatten_dt_nodes(blob,mem,dad,mynodes)
np = unflatten_dt_alloc(mem,sizeof(struct device_node)+allocl,__alignof__(struct device_node));
np->full_name = fn = ((char*)np) + sizeof(*np)
pp = unflatten_dt_alloc(mem,sizeof(struct property),__alignof__(struct property));
pp->name = (char *)pname;
pp->length = sz;
pp->value = (__be32 *)val;
- 在DTB文件中,每一个节点都以TAG(FDT_BEGIN_NODE,0x00000001)开始,节点内部可以嵌套其他节点,每一个属性都以TAG(FDT_PROP,0X00000003)开始
- 每一个节点都转换为一个device_node结构体
struct device_node{
const char *name;//来自节点中的name属性,如果没有该属性,则设置为"null"
const char *type;//来自节点中的device_type属性,如果没有该属性,则设为"null"
phandle phandle;
const char *full_name;//节点的名字,node-name[@uint-address]
struct fwnode_handle fwnode;
struct property *properties;//节点属性
struct property *deadprops;//removedproperties
struct device_node *patrent;//节点的父亲
struct device_node *child;//节点的孩子
struct device_node *sibling;//节点的兄弟
#if defined(CONFIG_OF_KOBJ)
struct kobject kobj;
#endif
unsigned long _flags;
void *data
};