diff --git a/FreeRTOS/Source/portable/esp8266/port.c b/FreeRTOS/Source/portable/esp8266/port.c
index b11a1c5..d27460a 100644
--- a/FreeRTOS/Source/portable/esp8266/port.c
+++ b/FreeRTOS/Source/portable/esp8266/port.c
@@ -172,9 +172,8 @@ portBASE_TYPE xPortStartScheduler( void )
     return pdTRUE;
 }
 
-/* Determine free heap size via libc sbrk function & mallinfo
+/* Determine free heap size via mallinfo
 
-   sbrk gives total size in totally unallocated memory,
    mallinfo.fordblks gives free space inside area dedicated to heap.
 
    mallinfo is possibly non-portable, although glibc & newlib both support
@@ -183,14 +182,7 @@ portBASE_TYPE xPortStartScheduler( void )
 size_t xPortGetFreeHeapSize( void )
 {
     struct mallinfo mi = mallinfo();
-    uint32_t brk_val = (uint32_t) sbrk(0);
-
-    intptr_t sp = (intptr_t)xPortSupervisorStackPointer;
-    if (sp == 0) {
-        /* scheduler not started */
-        SP(sp);
-    }
-    return sp - brk_val + mi.fordblks;
+    return mi.fordblks;
 }
 
 void vPortEndScheduler( void )
diff --git a/FreeRTOS/Source/tasks.c b/FreeRTOS/Source/tasks.c
index b7af046..8b18fa9 100644
--- a/FreeRTOS/Source/tasks.c
+++ b/FreeRTOS/Source/tasks.c
@@ -754,7 +754,11 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
 				/* Allocate space for the stack used by the task being created.
 				The base of the stack memory stored in the TCB so the task can
 				be deleted later if required. */
+
+                                /* Allocate the stack in dram, not iram. */
+                                uint32_t malloc_mask = set_malloc_regions(MALLOC_MASK_DRAM);
 				pxNewTCB->pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
+                                set_malloc_regions(malloc_mask);
 
 				if( pxNewTCB->pxStack == NULL )
 				{
@@ -769,7 +773,10 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB ) PRIVILEGED_FUNCTION;
 		StackType_t *pxStack;
 
 			/* Allocate space for the stack used by the task being created. */
+                        /* Allocate the stack in dram, not iram. */
+                        uint32_t malloc_mask = set_malloc_regions(MALLOC_MASK_DRAM);
 			pxStack = ( StackType_t * ) pvPortMalloc( ( ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ) ); /*lint !e961 MISRA exception as the casts are only redundant for some ports. */
+                        set_malloc_regions(malloc_mask);
 
 			if( pxStack != NULL )
 			{
@@ -990,7 +997,16 @@ UBaseType_t x;
 	{
 		/* Initialise this task's Newlib reent structure. */
 		_REENT_INIT_PTR( ( &( pxNewTCB->xNewLib_reent ) ) );
-	}
+
+                if (strcmp(pcName, "ppTask") == 0 ||
+                    strcmp(pcName, "rtc_timer_task") == 0 ||
+                    strcmp(pcName, "Tmr Svc") == 0) {
+                    pxNewTCB->xNewLib_reent.malloc_region_mask = MALLOC_MASK_DRAM;
+                } else {
+                    pxNewTCB->xNewLib_reent.malloc_region_mask = MALLOC_MASK_PREFER_DRAM;
+                    //pxNewTCB->xNewLib_reent.malloc_region_mask = MALLOC_MASK_PREFER_IRAM;
+                }
+        }
 	#endif
 
 	#if( INCLUDE_xTaskAbortDelay == 1 )
diff --git a/core/app_main.c b/core/app_main.c
index f854dce..a37d779 100644
--- a/core/app_main.c
+++ b/core/app_main.c
@@ -137,6 +137,9 @@ static void IRAM default_putc(char c) {
 void init_newlib_locks(void);
 extern uint8_t sdk_wDevCtrl[];
 void nano_malloc_insert_chunk(void *start, size_t size);
+extern uint8_t _heap_start[];
+extern uint8_t _text_end[];
+extern uint8_t enable_low_icache;
 
 // .text+0x258
 void IRAM sdk_user_start(void) {
@@ -209,8 +212,13 @@ void IRAM sdk_user_start(void) {
     cksum_value = buf32[5 + boot_slot];
     ic_flash_addr = (flash_sectors - 3 + boot_slot) * sdk_flashchip.sector_size;
     sdk_SPIRead(ic_flash_addr, buf32, sizeof(struct sdk_g_ic_saved_st));
+
+#ifdef ESP8266_ENABLE_LOW_ICACHE
+    enable_low_icache = ESP8266_ENABLE_LOW_ICACHE;
+#endif
     Cache_Read_Enable(0, 0, 1);
     zero_bss();
+
     sdk_os_install_putc1(default_putc);
 
     /* HACK Reclaim a region of unused bss from wdev.o. This would not be
@@ -219,6 +227,26 @@ void IRAM sdk_user_start(void) {
      * it is in very useful dram. */
     nano_malloc_insert_chunk((void *)(sdk_wDevCtrl + 0x2190), 8000);
 
+    /* Use all the used DRAM is for the dynamic heap. */
+    nano_malloc_insert_chunk(_heap_start, 0x3FFFC000 - (uintptr_t)_heap_start);
+
+    /* Add unused IRAM to the malloc free list. */
+    if (enable_low_icache) {
+        /* The memory region 0x40108000 to 0x4010C000 is used for icache so can
+         * not be used, but there might still be some unused IRAM */
+        nano_malloc_insert_chunk(_text_end, 0x40108000 - (uintptr_t)_text_end);
+    } else {
+        /* The memory region 0x40108000 to 0x4010C000 is not used as part of the
+         * instruction cache and is usable as extra IRAM. */
+        nano_malloc_insert_chunk(_text_end, 0x4010C000 - (uintptr_t)_text_end);
+    }
+
+    /* The preferred memory region to start allocate the early data. If the app
+     * has ample memory the use the DRAM, other if the app is running low on
+     * DRAM then it might help the allocated to the IRAM when possible. */
+    set_malloc_regions(MALLOC_MASK_PREFER_DRAM);
+    //set_malloc_regions(MALLOC_MASK_PREFER_IRAM);
+
     init_newlib_locks();
 
     if (cksum_magic == 0xffffffff) {
@@ -368,6 +396,7 @@ void sdk_user_init_task(void *params) {
     /* The start up stack is not used after scheduling has started, so all of
      * the top area of RAM which was stack can be used for the dynamic heap. */
     xPortSupervisorStackPointer = (void *)0x40000000;
+    nano_malloc_insert_chunk((void *)0x3FFFC000, 0x4000);
 
     sdk_ets_timer_init();
     printf("\nESP-Open-SDK ver: %s compiled @ %s %s\n", OS_VERSION_STR, __DATE__, __TIME__);
diff --git a/core/include/common_macros.h b/core/include/common_macros.h
index 7034787..3a07acf 100644
--- a/core/include/common_macros.h
+++ b/core/include/common_macros.h
@@ -117,5 +117,10 @@
     #define IROM __attribute__((section(".irom0.literal"))) const
 #endif
 
+uint32_t set_malloc_regions(uint32_t mask);
+#define MALLOC_MASK_PREFER_IRAM 0xfffdfffc
+#define MALLOC_MASK_PREFER_DRAM 0
+#define MALLOC_MASK_DRAM 0xfffffffe
+#define MALLOC_MASK_IRAM 0xfffffffd
 
 #endif
diff --git a/core/newlib_syscalls.c b/core/newlib_syscalls.c
index 50d0d30..d243a40 100644
--- a/core/newlib_syscalls.c
+++ b/core/newlib_syscalls.c
@@ -34,39 +34,30 @@
 #error Too many lwip sockets for the FD_SETSIZE.
 #endif
 
-extern void *xPortSupervisorStackPointer;
-
-IRAM void *_sbrk_r (struct _reent *r, ptrdiff_t incr)
+void *_sbrk_r (struct _reent *r, ptrdiff_t incr)
 {
-    extern char   _heap_start; /* linker script defined */
-    static char * heap_end;
-    char *        prev_heap_end;
-
-    if (heap_end == NULL)
-	heap_end = &_heap_start;
-    prev_heap_end = heap_end;
-
-    intptr_t sp = (intptr_t)xPortSupervisorStackPointer;
-    if(sp == 0) /* scheduler not started */
-        SP(sp);
-
-    if ((intptr_t)heap_end + incr >= sp)
-    {
-        r->_errno = ENOMEM;
-        return (caddr_t)-1;
-    }
-
-    heap_end += incr;
-
-    return (caddr_t) prev_heap_end;
+    r->_errno = ENOMEM;
+    return (caddr_t)-1;
 }
 
+/* If there is a restriction on the dram usage then skip this chunk if in dram,
+ * and if there is a restriction on the iram usage then skip this chunk if in
+ * iram */
+IRAM int _malloc_region_masked(void *r, unsigned int mask)
+{
+    if ( ((mask & 1) && (uint32_t)r < 0x40000000) ||
+         ((mask & 2) && (uint32_t)r >= 0x40100000) ) {
+        return 1;
+    }
 
-/* Insert a disjoint region into the nano malloc pool. Create a malloc chunk,
- * filling the size as newlib nano malloc expects, and then free it. */
-void nano_malloc_insert_chunk(void *start, size_t size) {
-    *(uint32_t *)start = size;
-    free(start + sizeof(size_t));
+    return 0;
+}
+
+uint32_t set_malloc_regions(uint32_t mask)
+{
+    uint32_t malloc_mask = _REENT->malloc_region_mask;
+    _REENT->malloc_region_mask = mask;
+    return malloc_mask;
 }
 
 /* syscall implementation for stdio write to UART */
diff --git a/extras/wificfg/wificfg.c b/extras/wificfg/wificfg.c
index 1e4c5d2..3e5f167 100644
--- a/extras/wificfg/wificfg.c
+++ b/extras/wificfg/wificfg.c
@@ -599,6 +599,11 @@ static const char *http_wificfg_content[] = {
 #include "content/wificfg/index.html"
 };
 
+extern unsigned nano_malloc_region_total_0;
+extern unsigned nano_malloc_region_free_0;
+extern unsigned nano_malloc_region_total_1;
+extern unsigned nano_malloc_region_free_1;
+
 static int handle_wificfg_index(int s, wificfg_method method,
                                 uint32_t content_length,
                                 wificfg_content_type content_type,
@@ -632,7 +637,19 @@ static int handle_wificfg_index(int s, wificfg_method method,
                  xTaskGetTickCount() * portTICK_PERIOD_MS / 1000);
         if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1;
 
-        snprintf(buf, len, "<dt>Free heap</dt><dd>%u bytes</dd>", (int)xPortGetFreeHeapSize());
+        snprintf(buf, len, "<dt>Free dram heap</dt><dd>%u of %u bytes</dd>",
+                 nano_malloc_region_free_0, nano_malloc_region_total_0);
+        if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1;
+
+        set_malloc_regions(MALLOC_MASK_IRAM);
+        snprintf(buf, len, "<dt>Free iram heap</dt><dd>%u of %u bytes</dd>",
+                 nano_malloc_region_free_1, nano_malloc_region_total_1);
+        if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1;
+
+        set_malloc_regions(MALLOC_MASK_PREFER_DRAM);
+        snprintf(buf, len, "<dt>Free heap</dt><dd>%u of %u bytes</dd>",
+                 nano_malloc_region_free_0 + nano_malloc_region_free_1,
+                 nano_malloc_region_total_0 + nano_malloc_region_total_1);
         if (wificfg_write_string_chunk(s, buf, buf, len) < 0) return -1;
 
         snprintf(buf, len, "<dt>Flash ID</dt><dd>0x%08x</dd>", sdk_spi_flash_get_id());
diff --git a/libc/README.md b/libc/README.md
index e3c84cb..04c6d2d 100644
--- a/libc/README.md
+++ b/libc/README.md
@@ -1,4 +1,4 @@
-Newlib from git://sourceware.org/git/newlib-cygwin.git with xtensa & locking patches see https://github.com/ourairquality/newlib and built from commit 984b749fb223daab954060c04720933290584f00
+Newlib from git://sourceware.org/git/newlib-cygwin.git with xtensa & locking patches see https://github.com/ourairquality/newlib and built from commit e06f70041061344a62c2e5b8f0a602a902e72306
 
 The build commands were:
 
diff --git a/libc/xtensa-lx106-elf/include/pthread.h b/libc/xtensa-lx106-elf/include/pthread.h
index 3dee1c9..c9d24d6 100644
--- a/libc/xtensa-lx106-elf/include/pthread.h
+++ b/libc/xtensa-lx106-elf/include/pthread.h
@@ -156,7 +156,7 @@ int	pthread_attr_getschedparam (const pthread_attr_t *__attr,
 int	pthread_getschedparam (pthread_t __pthread, int *__policy,
 			       struct sched_param *__param);
 int	pthread_setschedparam (pthread_t __pthread, int __policy,
-			       struct sched_param *__param);
+			       const struct sched_param *__param);
 
 /* Set Scheduling Priority of a Thread */
 int	pthread_setschedprio (pthread_t thread, int prio);
@@ -190,7 +190,7 @@ int	pthread_mutexattr_getprioceiling (const pthread_mutexattr_t *__attr,
 
 int	pthread_mutex_setprioceiling (pthread_mutex_t *__mutex,
 				      int __prioceiling, int *__old_ceiling);
-int	pthread_mutex_getprioceiling (pthread_mutex_t *__mutex,
+int	pthread_mutex_getprioceiling (const pthread_mutex_t *__restrict __mutex,
 				      int *__prioceiling);
 
 #endif /* _POSIX_THREAD_PRIO_PROTECT */
diff --git a/libc/xtensa-lx106-elf/include/stdlib.h b/libc/xtensa-lx106-elf/include/stdlib.h
index 5417ac0..87297ed 100644
--- a/libc/xtensa-lx106-elf/include/stdlib.h
+++ b/libc/xtensa-lx106-elf/include/stdlib.h
@@ -144,8 +144,7 @@ void	qsort (void *__base, size_t __nmemb, size_t __size, __compar_fn_t _compar);
 int	rand (void);
 void *	realloc (void *__r, size_t __size) _NOTHROW;
 #if __BSD_VISIBLE
-void	*reallocarray(void *, size_t, size_t) __result_use_check __alloc_size(2)
-	    __alloc_size(3);
+void	*reallocarray(void *, size_t, size_t) __result_use_check __alloc_size((2,3));
 void *	reallocf (void *__r, size_t __size);
 #endif
 #if __BSD_VISIBLE || __XSI_VISIBLE >= 4
@@ -329,8 +328,8 @@ extern long double strtold (const char *__restrict, char **__restrict);
  * If we're in a mode greater than C99, expose C11 functions.
  */
 #if __ISO_C_VISIBLE >= 2011
-void *	aligned_alloc(size_t, size_t) __malloc_like __alloc_align(1)
-	    __alloc_size(2);
+void *	aligned_alloc(size_t, size_t) __malloc_like __alloc_align((1))
+	    __alloc_size((2));
 int	at_quick_exit(void (*)(void));
 _Noreturn void
 	quick_exit(int);
diff --git a/libc/xtensa-lx106-elf/include/sys/_types.h b/libc/xtensa-lx106-elf/include/sys/_types.h
index 72e1dc1..d8e8c0b 100644
--- a/libc/xtensa-lx106-elf/include/sys/_types.h
+++ b/libc/xtensa-lx106-elf/include/sys/_types.h
@@ -193,7 +193,10 @@ typedef	_CLOCK_T_	__clock_t;
 #endif
 typedef	_TIME_T_	__time_t;
 
+#ifndef __machine_clockid_t_defined
 #define	_CLOCKID_T_ 	unsigned long
+#endif
+
 typedef	_CLOCKID_T_	__clockid_t;
 
 #define	_TIMER_T_	unsigned long
diff --git a/libc/xtensa-lx106-elf/include/sys/cdefs.h b/libc/xtensa-lx106-elf/include/sys/cdefs.h
index fc564a5..b3f8d19 100644
--- a/libc/xtensa-lx106-elf/include/sys/cdefs.h
+++ b/libc/xtensa-lx106-elf/include/sys/cdefs.h
@@ -258,12 +258,12 @@
 #define	__section(x)	__attribute__((__section__(x)))
 #endif
 #if __GNUC_PREREQ__(4, 3) || __has_attribute(__alloc_size__)
-#define	__alloc_size(x)	__attribute__((__alloc_size__(x)))
+#define	__alloc_size(x)	__attribute__((__alloc_size__ x))
 #else
 #define	__alloc_size(x)
 #endif
 #if __GNUC_PREREQ__(4, 9) || __has_attribute(__alloc_align__)
-#define	__alloc_align(x)	__attribute__((__alloc_align__(x)))
+#define	__alloc_align(x)	__attribute__((__alloc_align__ x))
 #else
 #define	__alloc_align(x)
 #endif
diff --git a/libc/xtensa-lx106-elf/include/sys/reent.h b/libc/xtensa-lx106-elf/include/sys/reent.h
index 0f21c68..27f68a3 100644
--- a/libc/xtensa-lx106-elf/include/sys/reent.h
+++ b/libc/xtensa-lx106-elf/include/sys/reent.h
@@ -174,9 +174,9 @@ extern void   __sinit (struct _reent *);
 	__sinit (ptr);				\
     }						\
   while (0)
-#else
+#else /* _REENT_SMALL && !_REENT_GLOBAL_STDIO_STREAMS */
 # define _REENT_SMALL_CHECK_INIT(ptr) /* nothing */
-#endif
+#endif /* _REENT_SMALL && !_REENT_GLOBAL_STDIO_STREAMS */
 
 struct __sFILE {
   unsigned char *_p;	/* current position in (some) buffer */
@@ -416,6 +416,8 @@ struct _reent
   __FILE *__sf;			        /* file descriptors */
   struct _misc_reent *_misc;            /* strtok, multibyte states */
   char *_signal_buf;                    /* strsignal */
+
+  unsigned int malloc_region_mask;
 };
 
 #ifdef _REENT_GLOBAL_STDIO_STREAMS
@@ -453,7 +455,7 @@ extern __FILE __sf[3];
     (var)->_stderr = &__sf[2]; \
   }
 
-#else
+#else /* _REENT_GLOBAL_STDIO_STREAMS */
 
 extern const struct __sFILE_fake __sf_fake_stdin;
 extern const struct __sFILE_fake __sf_fake_stdout;
@@ -482,7 +484,8 @@ extern const struct __sFILE_fake __sf_fake_stderr;
     {_NULL, 0, _NULL}, \
     _NULL, \
     _NULL, \
-    _NULL \
+    _NULL, \
+    0 \
   }
 
 #define _REENT_INIT_PTR_ZEROED(var) \
@@ -491,7 +494,7 @@ extern const struct __sFILE_fake __sf_fake_stderr;
     (var)->_stderr = (__FILE *)&__sf_fake_stderr; \
   }
 
-#endif
+#endif /* _REENT_GLOBAL_STDIO_STREAMS */
 
 /* Only add assert() calls if we are specified to debug.  */
 #ifdef _REENT_CHECK_DEBUG
diff --git a/libc/xtensa-lx106-elf/lib/crt0.o b/libc/xtensa-lx106-elf/lib/crt0.o
index efc11bc..57bed6b 100644
Binary files a/libc/xtensa-lx106-elf/lib/crt0.o and b/libc/xtensa-lx106-elf/lib/crt0.o differ
diff --git a/libc/xtensa-lx106-elf/lib/libc.a b/libc/xtensa-lx106-elf/lib/libc.a
index 457de25..70d9b12 100644
Binary files a/libc/xtensa-lx106-elf/lib/libc.a and b/libc/xtensa-lx106-elf/lib/libc.a differ
diff --git a/libc/xtensa-lx106-elf/lib/libg.a b/libc/xtensa-lx106-elf/lib/libg.a
index 457de25..70d9b12 100644
Binary files a/libc/xtensa-lx106-elf/lib/libg.a and b/libc/xtensa-lx106-elf/lib/libg.a differ
diff --git a/libc/xtensa-lx106-elf/lib/libm.a b/libc/xtensa-lx106-elf/lib/libm.a
index e7c0969..f9422f3 100644
Binary files a/libc/xtensa-lx106-elf/lib/libm.a and b/libc/xtensa-lx106-elf/lib/libm.a differ
diff --git a/lwip/esp_interface.c b/lwip/esp_interface.c
index 77ad177..c21a525 100644
--- a/lwip/esp_interface.c
+++ b/lwip/esp_interface.c
@@ -178,7 +178,9 @@ size_t ooseq_bytes_limit(struct tcp_pcb *pcb)
         ooseq_blen += p->tot_len;
     }
 
+    uint32_t malloc_mask = set_malloc_regions(MALLOC_MASK_DRAM);
     size_t free = xPortGetFreeHeapSize();
+    set_malloc_regions(malloc_mask);
     ssize_t target = ((ssize_t)free - 8000) + ooseq_blen;
 
     if (target < 0) {
diff --git a/lwip/lwip b/lwip/lwip
index d74e9ad..c1d2472 160000
--- a/lwip/lwip
+++ b/lwip/lwip
@@ -1 +1 @@
-Subproject commit d74e9ad2f7c9db996fb398cd41bf59ef463ae6fe
+Subproject commit c1d247296af423741f901bcfd4a8c2739e881565