linux device tree 解析DTB文件

/*
 * linux device tree 解析DTB文件
 */
    /* 内核启动时解析DTB文件的调用 */
    start_kernel -> setup_arch -> unflatten_device_tree ->
    __unflatten_device_tree -> unflatten_dt_nodes    (drivers/of/fdt.c)

    /* 节点处理函数 */
    查找节点的 of 函数
    of_find_node_by_name
    of_find_node_by_type
    of_find_compatible_node
    of_find_matching_node_and_match
    of_find_node_by_path

    查找父/子节点的 OF 函数
    of_get_parent
    of_get_next_child
    
    提取属性值的 OF 函数
    of_find_property
    of_property_count_elems_of_size
    of_property_read_u32_index
    of_property_read_u8_array
    of_property_read_u8
    of_property_read_string
    of_n_addr_cells
    of_n_size_cells
    of_iomap

    /* unflatten_device_tree */
    void __init unflatten_device_tree(void)
    {
        __unflatten_device_tree(initial_boot_params, NULL, &of_root,
                    early_init_dt_alloc_memory_arch, false);

        /* Get pointer to "/chosen" and "/aliases" nodes for use everywhere */
        of_alias_scan(early_init_dt_alloc_memory_arch);

        unittest_unflatten_overlay_base();
    }

    void *initial_boot_params;            (drivers/of/fdt.c)
    struct device_node *of_root;        (drivers/of/base.c)

    在 unflatten_device_tree() 中,调用函数 __unflatten_device_tree(),
    initial_boot_params 指向 Device Tree 在内存中的首地址,of_root 在经过该函数处理之后,会指向根节点.
    early_init_dt_alloc_memory_arch 是一个函数指针,为 struct device_node 和 struct property 结构体分配内存的回调函数(callback)。

    
    在 __unflatten_device_tree() 函数中,两次调用 unflatten_dt_node() 函数,

        /* First pass, scan for size */
        size = unflatten_dt_nodes(blob, NULL, dad, NULL);

        /* Second pass, do actual unflattening */
        unflatten_dt_nodes(blob, mem, dad, mynodes);

    第一次是为了得到 Device Tree 转换成 struct device_node 和 struct property 结构体需要分配的内存大小,
    第二次调用才是具体填充每一个 struct device_node 和 struct property 结构体。

    struct device_node {
        const char *name;
        const char *type;
        phandle phandle;                /* typedef u32 phandle */
        const char *full_name;
        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
    };

    struct property {
        char    *name;
        int    length;
        void    *value;
        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
    };

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值