diff --git a/common/Makefile b/common/Makefile
index aca0f7f..b7eafb5 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -255,6 +255,7 @@ obj-$(CONFIG_BOUNCE_BUFFER) += bouncebuf.o
 obj-y += console.o
 obj-$(CONFIG_CROS_EC) += cros_ec.o
 obj-y += dlmalloc.o
+obj-$(CONFIG_SYS_MALLOC_F_LEN) += malloc_simple.o
 obj-y += image.o
 obj-$(CONFIG_ANDROID_BOOT_IMAGE) += image-android.o
 obj-$(CONFIG_OF_LIBFDT) += image-fdt.o
diff --git a/common/board_r.c b/common/board_r.c
index cd92288..1d9b569 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -105,7 +105,8 @@ static int initr_trace(void)
 
 static int initr_reloc(void)
 {
-	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */
+	/* tell others: relocation done */
+	gd->flags |= GD_FLG_RELOC | GD_FLG_FULL_MALLOC_INIT;
 	bootstage_mark_name(BOOTSTAGE_ID_START_UBOOT_R, "board_init_r");
 
 	return 0;
diff --git a/common/dlmalloc.c b/common/dlmalloc.c
index f987339..16dc2ff 100644
--- a/common/dlmalloc.c
+++ b/common/dlmalloc.c
@@ -2181,17 +2181,8 @@ Void_t* mALLOc(bytes) size_t bytes;
   INTERNAL_SIZE_T nb;
 
 #ifdef CONFIG_SYS_MALLOC_F_LEN
-	if (!(gd->flags & GD_FLG_RELOC)) {
-		ulong new_ptr;
-		void *ptr;
-
-		new_ptr = gd->malloc_ptr + bytes;
-		if (new_ptr > gd->malloc_limit)
-			panic("Out of pre-reloc memory");
-		ptr = map_sysmem(gd->malloc_base + gd->malloc_ptr, bytes);
-		gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr));
-		return ptr;
-	}
+	if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT))
+		return malloc_simple(bytes);
 #endif
 
   /* check if mem_malloc_init() was run */
@@ -2459,7 +2450,7 @@ void fREe(mem) Void_t* mem;
 
 #ifdef CONFIG_SYS_MALLOC_F_LEN
 	/* free() is a no-op - all the memory will be freed on relocation */
-	if (!(gd->flags & GD_FLG_RELOC))
+	if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT))
 		return;
 #endif
 
@@ -2615,7 +2606,7 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes;
   if (oldmem == NULL) return mALLOc(bytes);
 
 #ifdef CONFIG_SYS_MALLOC_F_LEN
-	if (!(gd->flags & GD_FLG_RELOC)) {
+	if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
 		/* This is harder to support and should not be needed */
 		panic("pre-reloc realloc() is not supported");
 	}
@@ -2967,7 +2958,7 @@ Void_t* cALLOc(n, elem_size) size_t n; size_t elem_size;
   else
   {
 #ifdef CONFIG_SYS_MALLOC_F_LEN
-	if (!(gd->flags & GD_FLG_RELOC)) {
+	if (!(gd->flags & GD_FLG_FULL_MALLOC_INIT)) {
 		MALLOC_ZERO(mem, sz);
 		return mem;
 	}
diff --git a/common/malloc_simple.c b/common/malloc_simple.c
new file mode 100644
index 0000000..bed227a
--- /dev/null
+++ b/common/malloc_simple.c
@@ -0,0 +1,38 @@
+/*
+ * Simple malloc implementation
+ *
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <malloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void *malloc_simple(size_t bytes)
+{
+	ulong new_ptr;
+	void *ptr;
+
+	new_ptr = gd->malloc_ptr + bytes;
+	if (new_ptr > gd->malloc_limit)
+		panic("Out of pre-reloc memory");
+	ptr = map_sysmem(gd->malloc_base + gd->malloc_ptr, bytes);
+	gd->malloc_ptr = ALIGN(new_ptr, sizeof(new_ptr));
+	return ptr;
+}
+
+#ifdef CONFIG_SYS_MALLOC_SIMPLE
+void *calloc(size_t nmemb, size_t elem_size)
+{
+	size_t size = nmemb * elem_size;
+	void *ptr;
+
+	ptr = malloc(size);
+	memset(ptr, '\0', size);
+
+	return ptr;
+}
+#endif
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
index 74df210..5e5dc37 100644
--- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h
@@ -107,5 +107,6 @@ typedef struct global_data {
 #define GD_FLG_DISABLE_CONSOLE	0x00040	/* Disable console (in & out)	   */
 #define GD_FLG_ENV_READY	0x00080	/* Env. imported into hash table   */
 #define GD_FLG_SERIAL_READY	0x00100	/* Pre-reloc serial console ready  */
+#define GD_FLG_FULL_MALLOC_INIT	0x00200	/* Full malloc() is ready	   */
 
 #endif /* __ASM_GENERIC_GBL_DATA_H */
diff --git a/include/malloc.h b/include/malloc.h
index c33f3b4..5df6348 100644
--- a/include/malloc.h
+++ b/include/malloc.h
@@ -872,33 +872,46 @@ extern Void_t*     sbrk();
 
 #else
 
-#ifdef USE_DL_PREFIX
-#define cALLOc		dlcalloc
-#define fREe		dlfree
-#define mALLOc		dlmalloc
-#define mEMALIGn	dlmemalign
-#define rEALLOc		dlrealloc
-#define vALLOc		dlvalloc
-#define pvALLOc		dlpvalloc
-#define mALLINFo	dlmallinfo
-#define mALLOPt		dlmallopt
-#else /* USE_DL_PREFIX */
-#define cALLOc		calloc
-#define fREe		free
-#define mALLOc		malloc
-#define mEMALIGn	memalign
-#define rEALLOc		realloc
-#define vALLOc		valloc
-#define pvALLOc		pvalloc
-#define mALLINFo	mallinfo
-#define mALLOPt		mallopt
-#endif /* USE_DL_PREFIX */
+#ifdef CONFIG_SYS_MALLOC_SIMPLE
+#define malloc malloc_simple
+#define realloc realloc_simple
+#define memalign memalign_simple
+static inline void free(void *ptr) {}
+void *calloc(size_t nmemb, size_t size);
+void *memalign_simple(size_t alignment, size_t bytes);
+void *realloc_simple(void *ptr, size_t size);
+#else
+
+# ifdef USE_DL_PREFIX
+# define cALLOc		dlcalloc
+# define fREe		dlfree
+# define mALLOc		dlmalloc
+# define mEMALIGn	dlmemalign
+# define rEALLOc		dlrealloc
+# define vALLOc		dlvalloc
+# define pvALLOc		dlpvalloc
+# define mALLINFo	dlmallinfo
+# define mALLOPt		dlmallopt
+# else /* USE_DL_PREFIX */
+# define cALLOc		calloc
+# define fREe		free
+# define mALLOc		malloc
+# define mEMALIGn	memalign
+# define rEALLOc		realloc
+# define vALLOc		valloc
+# define pvALLOc		pvalloc
+# define mALLINFo	mallinfo
+# define mALLOPt		mallopt
+# endif /* USE_DL_PREFIX */
 
 #endif
 
 /* Public routines */
 
-#if __STD_C
+/* Simple versions which can be used when space is tight */
+void *malloc_simple(size_t size);
+
+# if __STD_C
 
 Void_t* mALLOc(size_t);
 void    fREe(Void_t*);
@@ -913,7 +926,7 @@ size_t  malloc_usable_size(Void_t*);
 void    malloc_stats(void);
 int     mALLOPt(int, int);
 struct mallinfo mALLINFo(void);
-#else
+# else
 Void_t* mALLOc();
 void    fREe();
 Void_t* rEALLOc();
@@ -927,6 +940,7 @@ size_t  malloc_usable_size();
 void    malloc_stats();
 int     mALLOPt();
 struct mallinfo mALLINFo();
+# endif
 #endif
 
 /*
