diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 9b8af65052b8ff67b068dc95e5dbb60d1acb8f6b..b213ef172d9ec97fac61bf21f37272038e76913c 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -12,7 +12,7 @@
 #include <errno.h>
 #include <libfdt.h>
 #include <libfdt_env.h>
-#include <malloc.h>
+#include <memalign.h>
 #include <asm/global_data.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -104,12 +104,34 @@ static struct efi_object bootefi_device_obj = {
 static void *copy_fdt(void *fdt)
 {
 	u64 fdt_size = fdt_totalsize(fdt);
+	unsigned long fdt_ram_start = -1L, fdt_pages;
+	u64 new_fdt_addr;
 	void *new_fdt;
+	int i;
 
-	/* Give us 64kb breathing room */
-	fdt_size += 64 * 1024;
+        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+                u64 ram_start = gd->bd->bi_dram[i].start;
+                u64 ram_size = gd->bd->bi_dram[i].size;
 
-	new_fdt = malloc(fdt_size);
+		if (!ram_size)
+			continue;
+
+		if (ram_start < fdt_ram_start)
+			fdt_ram_start = ram_start;
+	}
+
+	/* Give us at least 4kb breathing room */
+	fdt_size = ALIGN(fdt_size + 4096, 4096);
+	fdt_pages = fdt_size >> EFI_PAGE_SHIFT;
+
+	/* Safe fdt location is at 128MB */
+	new_fdt_addr = fdt_ram_start + (128 * 1024 * 1024) + fdt_size;
+	if (efi_allocate_pages(1, EFI_BOOT_SERVICES_DATA, fdt_pages,
+			       &new_fdt_addr) != EFI_SUCCESS) {
+		/* If we can't put it there, put it somewhere */
+		new_fdt_addr = (ulong)memalign(4096, fdt_size);
+	}
+	new_fdt = (void*)(ulong)new_fdt_addr;
 	memcpy(new_fdt, fdt, fdt_totalsize(fdt));
 	fdt_set_totalsize(new_fdt, fdt_size);