Advertisement

UBOOT设备树研究

阅读量:

文章目录

  • 1、介绍
  • 2、设备树的获取与设置
  • 3、uboot如何获取dtb
  • 4、uboot设备树接口

1、介绍

在运行uboot的过程中可以对系统的某些硬件架构进行初步设置,在依据设置决定具体的硬件布局后

fdt具有极高的易用性,在配置与管理上表现出色;采用节点与属性作为核心配置手段,并通过层次化的管理方式实现系统的优化;当存在多种不同的硬件板时,则能够基于同一套源代码实现功能扩展,在实际应用中只需稍作修改即可完成对各层级硬件的匹配工作

2、设备树的获取与设置

设备树可通过 kernel 源码获取,在 uboot 引导下 kernel 启动。若将 kernel 中的设备树迁移至 uboot 中,则同样能直接使用。

通过以下代码进行配置设备树

#define CONFIG_DEFAULT_DEVICE_TREE “”

设备树通过构建(代替编译),不仅可以在uboot的尾部完成构建(代替编译),也可以嵌入到uboot内部。此外,在配置fdtcontroladdr环境变量的情况下,则可以使设备树被加载至特定地址的位置上。通过这种方式,在不同的板级信息下加载不同的设备树(代替方式),能够实现相同的代码在不同板子上的适配效果(代替目的)。

3、uboot如何获取dtb

复制代码
    [common/board_f.c]
    static init_fnc_t init_sequence_f[] = {
    ···
    #ifdef CONFIG_OF_CONTROL
    	fdtdec_setup,//获取设备树地址
    #endif
    ···
    #ifdef CONFIG_OF_CONTROL
    	fdtdec_prepare_fdt,//判断设备树地址是否正确
    #endif
    ···
    	reserve_fdt,//为fdt分配内存
    ···
    	reloc_fdt,//重载fdt
    ···
    	NULL,
    };
    
    
    AI生成项目c
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/AD0bLRrQMHUyt8jTBmp1WNdeSJYk.png)

以上是board_init_f当中对于fdt的操作。

复制代码
    int fdtdec_setup(void)
    {
    #if CONFIG_IS_ENABLED(OF_CONTROL)
    # ifdef CONFIG_OF_EMBED
    	/* Get a pointer to the FDT */
    	gd->fdt_blob = __dtb_dt_begin;//如果使用
    # elif defined CONFIG_OF_SEPARATE
    #  ifdef CONFIG_SPL_BUILD
    	/* FDT is at end of BSS unless it is in a different memory region */
    	if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS))
    		gd->fdt_blob = (ulong *)&_image_binary_end;
    	else
    		gd->fdt_blob = (ulong *)&__bss_end;
    #  else
    	/* FDT is at end of image */
    	gd->fdt_blob = (ulong *)&_end;
    #  endif
    # elif defined(CONFIG_OF_HOSTFILE)
    	if (sandbox_read_fdt_from_file()) {
    		puts("Failed to read control FDT\n");
    		return -1;
    	}
    # endif
    # ifndef CONFIG_SPL_BUILD
    	/* Allow the early environment to override the fdt address */
    	gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16,
    						(uintptr_t)gd->fdt_blob);
    # endif
    #endif
    	return fdtdec_prepare_fdt();
    }
    
    
    AI生成项目c
    
    
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-07-13/PH4EwzbVZKCc6nMSk7iD50RdGfse.png)
复制代码
    int fdtdec_prepare_fdt(void)
    {
    	if (!gd->fdt_blob || ((uintptr_t)gd->fdt_blob & 3) ||
    	    fdt_check_header(gd->fdt_blob)) {
    	···//如果有错则打印一些信息,主要进行以上的判断
    		return -1;
    	}
    	return 0;//如果无错误,则直接返回0
    }
    
    
    AI生成项目c

对设备树的地址进行判断,检查设备树的头,确认设备树正确。

4、uboot设备树接口

该变量gd->fdt_blob已被成功配置为指向dtb地址

以下仅用于概述几个接口的作用。另外,在dtb中使用偏移地址的方式将节点表示为一个位置。即为node变量中存储了该节点的偏移地址位置。

在lib/fdtdec.c文件中,在# define FDT_PATH_OFFSET后,
函数int FDT_PATH_OFFSET(const struct fdt_node **fdt, const char *path)的功能是获取dtb中某个节点路径path相对于该节点的位置偏移量。
例如:
node = fdt_path_offset(gd->fdt_node, "subtree");
其中gd->fdt_node表示当前节点的FDX表头指针变量。

  • fdt_getprop
    ( const pointer to fdt object , int nodeoffset , const string name , pointer to int variable lenp )
    eg: 获取节点node的mac地址,并将其赋值给变量mac.
    功能: 该函数用于从指定节点中获取其对应属性的具体值.

    复制代码
    * **fdtdec_get_int_array、fdtdec_get_byte_array**  

int fdtdec_get_int_array(const void *blob, int node, const char *prop_name, u32 *array, int count)
eg: ret = fdtdec_get_int_array(blob, node, “interrupts”, cell, ARRAY_SIZE(cell));
功能:获得节点node的某个整形数组属性值。

fdtdec_get_addr
ftd\_addr\_t fdtdec\_get\_addr\left(const\ void\ *\*blob,\ int\ node,\ const\ char\ *\ prop\_name\right)
例如,在使用该函数时,请注意如下调用方式:eg.fdtdec_get_addr(blob, node, "reg");
功能:获取指定节点node的地址属性值。

  • ftdtc_get_config_int, ftdtc_get_config_bool, ftdtc_get_config_string
    功能:该模块用于获取配置节点下的整数值属性、布尔值属性以及字符串类型信息。

此为改写后的文本

  • fdtdec_get_chosen_prop
    const char *fdtdec_get_chosen_prop(const void *blob, const char *name)
    功能:返回指定名称的属性值

    • lib/fdtdec_common.c中
      • fdtdec_get_int
        int fdtdec_get_int(const void *blob, int node, const char *prop_name, int default_val)
        eg: bus->udelay = fdtdec_get_int(blob, node, “i2c-gpio,delay-us”, DEFAULT_UDELAY);
        功能:获得节点node的某个整形属性值。

      • fdtdec_get_uint
        功能:获得节点node的某个无符号整形属性值。

该接口基于uboot的设备驱动模型进行设计后, 会使开发过程变得容易一些。后续将深入探讨基于设备树实现的驱动方案。

全部评论 (0)

还没有任何评论哟~