diff --git a/headers/private/kernel/boot/platform/u-boot/platform_stage2_args.h b/headers/private/kernel/boot/platform/u-boot/platform_stage2_args.h index d47bbb3c66..966fd1761e 100644 --- a/headers/private/kernel/boot/platform/u-boot/platform_stage2_args.h +++ b/headers/private/kernel/boot/platform/u-boot/platform_stage2_args.h @@ -12,6 +12,8 @@ struct platform_stage2_args { void *boot_tgz_data; uint32 boot_tgz_size; + void *fdt_data; + uint32 fdt_size; }; #endif /* KERNEL_BOOT_PLATFORM_UBOOT_STAGE2_H */ diff --git a/src/system/boot/platform/u-boot/start.cpp b/src/system/boot/platform/u-boot/start.cpp index 81b03bf03c..898830f0aa 100644 --- a/src/system/boot/platform/u-boot/start.cpp +++ b/src/system/boot/platform/u-boot/start.cpp @@ -172,11 +172,33 @@ start_raw(int argc, const char **argv) args.arguments = NULL; args.platform.boot_tgz_data = NULL; args.platform.boot_tgz_size = 0; + args.platform.fdt_data = NULL; + args.platform.fdt_size = 0; + + // if we get passed a uimage, try to find the third blob only if we do not have FDT data yet + if (gUImage != NULL + && !gFDT + && image_multi_getimg(gUImage, 2, + (uint32*)&args.platform.fdt_data, + &args.platform.fdt_size)) { + // found a blob, assume it is FDT data, when working on a platform + // which does not have an FDT enabled U-Boot + gFDT = args.platform.fdt_data; + } serial_init(gFDT); console_init(); cpu_init(); + if (args.platform.fdt_data) { + dprintf("Found FDT from uimage @ %p, %" B_PRIu32 " bytes\n", + args.platform.fdt_data, args.platform.fdt_size); + } else if (gFDT) { + /* Fixup args so we can pass the gFDT on to the kernel */ + args.platform.fdt_data = gFDT; + args.platform.fdt_size = fdt_totalsize(gFDT); + } + // if we get passed an FDT, check /chosen for initrd if (gFDT != NULL) { int node = fdt_path_offset(gFDT, "/chosen");