2 fdtdec_setup:如果u-boot中使用设备树,则需处理一些相关工作
第一篇文章查看.config配置文件知道关于设备树就有下面几个定义:
CONFIG_OF_CONTROL=y
CONFIG_OF_SEPARATE=y
CONFIG_OF_TRANSLATE=y
CONFIG_OF_LIBFDT=y
所以去掉宏定义之后的函数定义就是:
/* file: lib/fdtdec.c */
int fdtdec_setup(void)
{
int ret;
/* Allow the board to override the fdt address. */
gd->fdt_blob = board_fdt_blob_setup();
/* Allow the early environment to override the fdt address */
gd->fdt_blob = map_sysmem
(env_get_ulong("fdtcontroladdr", 16,
(unsigned long)map_to_sysmem(gd->fdt_blob)), 0);
ret = fdtdec_prepare_fdt();
if (!ret)
ret = fdtdec_board_setup(gd->fdt_blob);
return ret;
}
函数先是调用board_fdt_blob_setup来设置gd结构体的fdt_blob成员,简化宏定义之后函数如下:
/* file: lib/fdtdec.c */
__weak void *board_fdt_blob_setup(void)
{
void *fdt_blob = NULL;
/* FDT is at end of image */
fdt_blob = (ulong *)&_end;
return fdt_blob;
}
由前面的镜像组成可以知道u-boot设备树文件是放在u-boot.bin的末尾,所以取它的地址返回即可。 后面继续调用env_get_ulong从环境变量中获取u-boot设备树的地址,如果该环境变量没有被设置则返回原本的默认值(unsigned long)map_to_sysmem(gd->fdt_blob)。最终继续调用fdtdec_prepare_fdt函数来打印一些信息:
/* file: lib/fdtdec.c */
int fdtdec_prepare_fdt(void)
{
if (!gd->fdt_blob || ((uintptr_t)gd->fdt_blob & 3) ||
fdt_check_header(gd->fdt_blob)) {
#ifdef CONFIG_SPL_BUILD
puts("Missing DTB\n");
#else
puts("No valid device tree binary found - please append one to U-Boot binary, use u-boot-dtb.bin or define CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n");
# ifdef DEBUG
if (gd->fdt_blob) {
printf("fdt_blob=%p\n", gd->fdt_blob);
print_buffer((ulong)gd->fdt_blob, gd->fdt_blob, 4,
32, 0);
}
# endif
#endif
return -1;
}
return 0;
}