diff --git a/Makefile b/Makefile
index 4722f6121aa1fa0de8ea460521bcde7c78543460..6c8092c395ce60ea16c806f71d2a1011ae067d4a 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ SUBDIRS := miosix
 ## List here your source files (both .s, .c and .cpp)
 ##
 SRC :=                                  \
-main.cpp pool_allocator.cpp
+main.cpp
 
 ##
 ## List here additional static libraries with relative path
diff --git a/app_template/Makefile b/app_template/Makefile
index 103b25409e85b0c87b666f67a0d11251c43ef299..d27419d1ea8077628c031476ed91691824b477d2 100644
--- a/app_template/Makefile
+++ b/app_template/Makefile
@@ -28,7 +28,7 @@ all: $(OBJ) crt0.o
 	$(CXX) $(LFLAGS) -o main.elf $(OBJ) crt0.o $(LINK_LIBS)
 	$(SZ)  main.elf
 	@arm-miosix-eabi-objdump -Dslx main.elf > main.txt
-	@mx-postlinker main.elf --ramsize=20480 --stacksize=2048 --strip-sectheader
+	@mx-postlinker main.elf --ramsize=16384 --stacksize=2048 --strip-sectheader
 	@xxd -i main.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h
 
 clean:
diff --git a/app_template/prog3.h b/app_template/prog3.h
index 17c4af007efb5a433d92a54af598470efc7abc0e..a7a34f4a927292447b84f09e07c22e9b7264599d 100644
--- a/app_template/prog3.h
+++ b/app_template/prog3.h
@@ -29,7 +29,7 @@ const unsigned char __attribute__((aligned(8))) main_elf[] = {
   0x70, 0x47, 0x04, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x05, 0x23, 0x00, 0xdf,
   0x70, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00,
-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x50, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x40, 0x00, 0x00,
   0x01, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x4d, 0x69, 0x6f, 0x73,
   0x69, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x30, 0x3d, 0x64, 0x69, 0x76, 0x7a, 0x65, 0x72,
diff --git a/miosix/Makefile b/miosix/Makefile
index 78f53e7e9a4a4f0829669e32865fac0c785dce07..559c5cc08a430802946c9ea7a340eb26a511d861 100644
--- a/miosix/Makefile
+++ b/miosix/Makefile
@@ -19,6 +19,7 @@ kernel/stage_2_boot.cpp                                                    \
 kernel/syscalls.cpp                                                        \
 kernel/elf_program.cpp                                                     \
 kernel/process.cpp                                                         \
+kernel/process_pool.cpp                                                    \
 kernel/scheduler/priority/priority_scheduler.cpp                           \
 kernel/scheduler/control/control_scheduler.cpp                             \
 kernel/scheduler/edf/edf_scheduler.cpp                                     \
diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_xram_processes.ld b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_xram_processes.ld
new file mode 100644
index 0000000000000000000000000000000000000000..3b00c3b09df422098399799c2df18859b919d5f5
--- /dev/null
+++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_xram_processes.ld
@@ -0,0 +1,171 @@
+/*
+ * C++ enabled linker script for stm32 (1M FLASH, 128K RAM) + 2MB xram
+ * Developed by TFT: Terraneo Federico Technologies
+ * Optimized for use with the Miosix kernel
+ */
+
+/*
+ * This linker script puts:
+ * - read only data and code (.text, .rodata, .eh_*) in flash
+ * - stack for interrupt handling, sections .data and .bss in the internal ram
+ * - heap and stack of threads in the external ram
+ * - 1MB of process pool, for allocation of processes
+ */
+
+/*
+ * The main stack is used for interrupt handling by the kernel.
+ *
+ * *** Readme ***
+ * This linker script places the main stack (used by the kernel for interrupts)
+ * at the bottom of the ram, instead of the top. This is done for two reasons:
+ *
+ * - as an optimization for microcontrollers with little ram memory. In fact
+ *   the implementation of malloc from newlib requests memory to the OS in 4KB
+ *   block (except the first block that can be smaller). This is probably done
+ *   for compatibility with OSes with an MMU and paged memory. To see why this
+ *   is bad, consider a microcontroller with 8KB of ram: when malloc finishes
+ *   up the first 4KB it will call _sbrk_r asking for a 4KB block, but this will
+ *   fail because the top part of the ram is used by the main stack. As a
+ *   result, the top part of the memory will not be used by malloc, even if
+ *   available (and it is nearly *half* the ram on an 8KB mcu). By placing the
+ *   main stack at the bottom of the ram, the upper 4KB block will be entirely
+ *   free and available as heap space.
+ *
+ * - In case of main stack overflow the cpu will fault because access to memory
+ *   before the beginning of the ram faults. Instead with the default stack
+ *   placement the main stack will silently collide with the heap.
+ * Note: if increasing the main stack size also increase the ORIGIN value in
+ * the MEMORY definitions below accordingly.
+ */
+_main_stack_size = 0x00000200;                     /* main stack = 512Bytes */
+_main_stack_top  = 0x20000000 + _main_stack_size;
+ASSERT(_main_stack_size   % 8 == 0, "MAIN stack size error");
+
+/* Mapping the heap into external RAM  (1MB as the second half is for the
+ * process pool) */
+_end = 0x64000000;
+_heap_end = 0x64100000;
+_process_pool_start = _heap_end;
+_process_pool_end = 0x64200000;
+
+/* identify the Entry Point  */
+ENTRY(_Z13Reset_Handlerv)
+
+/* specify the memory areas  */
+MEMORY
+{
+    flash(rx)   : ORIGIN = 0,          LENGTH = 1M
+
+    /*
+     * Note, the ram starts at 0x20000000 but it is necessary to add the size
+     * of the main stack, so it is 0x20000200.
+     */
+    ram(wx)     : ORIGIN = 0x20000200, LENGTH =  128K-0x200
+}
+
+/* now define the output sections  */
+SECTIONS
+{
+    . = 0;
+    
+    /* .text section: code goes to flash */
+    .text :
+    {
+        /* Startup code must go at address 0 */
+        KEEP(*(.isr_vector))
+        
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+        /* these sections for thumb interwork? */
+        *(.glue_7)
+        *(.glue_7t)
+        /* these sections for C++? */
+        *(.gcc_except_table)
+        *(.gcc_except_table.*)
+        *(.ARM.extab*)
+        *(.gnu.linkonce.armextab.*)
+
+        . = ALIGN(4);
+        /* .rodata: constant data */
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+
+        /* C++ Static constructors/destructors (eabi) */
+        . = ALIGN(4);
+        KEEP(*(.init))
+
+        . = ALIGN(4);
+        __preinit_array_start = .;
+        KEEP (*(.preinit_array))
+        __preinit_array_end = .;
+
+        . = ALIGN(4);
+        __init_array_start = .;
+        KEEP (*(SORT(.init_array.*)))
+        KEEP (*(.init_array))
+        __init_array_end = .;
+
+        . = ALIGN(4);
+        KEEP(*(.fini))
+
+        . = ALIGN(4);
+        __fini_array_start = .;
+        KEEP (*(.fini_array))
+        KEEP (*(SORT(.fini_array.*)))
+        __fini_array_end = .;
+
+        /* C++ Static constructors/destructors (elf)  */
+        . = ALIGN(4);
+        _ctor_start = .;
+        KEEP (*crtbegin.o(.ctors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
+        KEEP (*(SORT(.ctors.*)))
+        KEEP (*crtend.o(.ctors))
+       _ctor_end = .;
+
+        . = ALIGN(4);
+        KEEP (*crtbegin.o(.dtors))
+        KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
+        KEEP (*(SORT(.dtors.*)))
+        KEEP (*crtend.o(.dtors))
+    } > flash
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > flash
+    __exidx_end = .;
+
+    . = ALIGN(8);
+    _etext = .;
+
+	/* .data section: global variables go to ram, but also store a copy to
+       flash to initialize them */
+    .data : ALIGN(8)
+    {
+        _data = .;
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+        . = ALIGN(8);
+        _edata = .;
+    } > ram AT > flash
+
+    /* .bss section: uninitialized global variables go to ram */
+    _bss_start = .;
+    .bss :
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        . = ALIGN(8);
+    } > ram
+    _bss_end = .;
+
+    /*_end = .;*/
+    /*PROVIDE(end = .);*/
+}
diff --git a/miosix/config/Makefile.inc b/miosix/config/Makefile.inc
index ef5b472f868c36c3e4a30fde3ee3f7bf09e44f1d..d9604d7e8f478cece00c8d8e0142193f382a619c 100644
--- a/miosix/config/Makefile.inc
+++ b/miosix/config/Makefile.inc
@@ -27,8 +27,8 @@ OPT_BOARD := stm32f207ig_stm3220g-eval
 ## -O2 is recomended otherwise, as it provides a good balance between code
 ## size and speed
 ##
-OPT_OPTIMIZATION := -O0
-#OPT_OPTIMIZATION := -O2
+#OPT_OPTIMIZATION := -O0
+OPT_OPTIMIZATION := -O2
 #OPT_OPTIMIZATION := -O3
 #OPT_OPTIMIZATION := -Os
 
@@ -154,12 +154,15 @@ ifeq ($(OPT_BOARD),stm32f207ig_stm3220g-eval)
     ##    *very* slow compared to FLASH. Works only with a booloader that
     ##    forwards interrrupts @ 0x64000000 (see miosix/bootloaders for one).
     ##    The microcontroller must have an external memory interface.
+    ## 4) Same as 3) but space has been reserved for a process pool, allowing
+    ##    to configure the kernel with "#define WITH_PROCESSES"
     ## Warning! enable external ram if you use a linker script that requires it
     ## (see the XRAM flag below)
     LINKER_SCRIPT_PATH := arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/
     #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+128k_rom.ld
     #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+128k_xram.ld
-    LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+128k_all_in_xram.ld
+    #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+128k_all_in_xram.ld
+    LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+128k_xram_processes.ld
 
     ## Enable/disable initialization of external RAM at boot. Three options:
     ## __ENABLE_XRAM : If you want the heap in xram (with an appropriate linker
@@ -651,10 +654,13 @@ else ifeq ($(ARCH),cortexM3_stm32f2)
         ## error message saying that 'make program' is not supported for that
         ## board.
         ifeq ($(LINKER_SCRIPT),$(LINKER_SCRIPT_PATH)stm32_1m+128k_all_in_xram.ld)
-        PROGRAM_CMDLINE := miosix/bootloaders/stm32/pc_loader/pc_loader \
-        /dev/ttyUSB0 main.bin
+            PROGRAM_CMDLINE := miosix/bootloaders/stm32/pc_loader/pc_loader \
+                /dev/ttyUSB0 main.bin
+        else ifeq ($(LINKER_SCRIPT),$(LINKER_SCRIPT_PATH)stm32_1m+128k_xram_processes.ld)
+            PROGRAM_CMDLINE := miosix/bootloaders/stm32/pc_loader/pc_loader \
+                /dev/ttyUSB0 main.bin
         else
-        PROGRAM_CMDLINE := qstlink2 -cqewV ./main.bin
+            PROGRAM_CMDLINE := qstlink2 -cqewV ./main.bin
         endif
 
     ##-------------------------------------------------------------------------
diff --git a/miosix/kernel/elf_program.cpp b/miosix/kernel/elf_program.cpp
index 85d81f199cfa54bce572034e69c865e27b3d3916..caaeace23d70e22547c9c1cead85c53fa88a8008 100644
--- a/miosix/kernel/elf_program.cpp
+++ b/miosix/kernel/elf_program.cpp
@@ -26,6 +26,7 @@
  ***************************************************************************/
 
 #include "elf_program.h"
+#include "process_pool.h"
 #include <stdexcept>
 #include <cstring>
 #include <cstdio>
@@ -43,6 +44,17 @@ namespace miosix {
 ///By convention, in an elf file for Miosix, the data segment starts @ this addr
 static const unsigned int DATA_START=0x10000000;
 
+ProcessPool& getProcessPool()
+{
+    //These are defined in the linker script
+	extern unsigned int _process_pool_start asm("_process_pool_start");
+	extern unsigned int _process_pool_end asm("_process_pool_end");
+    static ProcessPool pool(
+        reinterpret_cast<unsigned int*>(_process_pool_start),
+        _process_pool_end-_process_pool_start);
+    return pool;
+}
+
 //
 // class ElfProgram
 //
@@ -228,7 +240,7 @@ bool ElfProgram::validateDynamicSegment(const Elf32_Phdr *dynamic,
 
 void ProcessImage::load(const ElfProgram& program)
 {
-    if(image) delete[] image;
+    if(image) getProcessPool().deallocate(image);
     size=MAX_PROCESS_IMAGE_SIZE;
     const unsigned int base=program.getElfBase();
     const Elf32_Phdr *phdr=program.getProgramHeaderTable();
@@ -262,7 +274,7 @@ void ProcessImage::load(const ElfProgram& program)
                             dtRelsz=dyn->d_un.d_val;
                             break;
                         case DT_MX_RAMSIZE:
-                            image=new unsigned int[dyn->d_un.d_val/4];
+                            image=getProcessPool().allocate(dyn->d_un.d_val);
                         default:
                             break;
                     }
@@ -306,7 +318,7 @@ void ProcessImage::load(const ElfProgram& program)
 
 ProcessImage::~ProcessImage()
 {
-    if(image) delete[] image;
+    if(image) getProcessPool().deallocate(image);
 }
 
 } //namespace miosix
diff --git a/process_pool.cpp b/miosix/kernel/process_pool.cpp
similarity index 86%
rename from process_pool.cpp
rename to miosix/kernel/process_pool.cpp
index 36e3fa4e7a906fae5c2a1a72b40275bc4f024f11..714831e0c1a7629f51279e45bad08dfc0444452d 100644
--- a/process_pool.cpp
+++ b/miosix/kernel/process_pool.cpp
@@ -13,7 +13,7 @@ ProcessPool::ProcessPool(unsigned int *poolBase, unsigned int poolSize)
     memset(bitmap,0,numBytes);
 }
     
-unsigned int *ProcessPool::allocate(int size)
+unsigned int *ProcessPool::allocate(unsigned int size)
 {
     #ifndef TEST_ALLOC
     miosix::Lock<miosix::FastMutex> l(mutex);
@@ -25,21 +25,21 @@ unsigned int *ProcessPool::allocate(int size)
     unsigned int offset=0;
     if(reinterpret_cast<unsigned int>(poolBase) % size)
         offset=size-(reinterpret_cast<unsigned int>(poolBase) % size);
-    int startBit=offset/blockSize;
-    int sizeBit=size/blockSize;
+    unsigned int startBit=offset/blockSize;
+    unsigned int sizeBit=size/blockSize;
 
-    for(int i=startBit;i<=poolSize/blockSize;i+=sizeBit)
+    for(unsigned int i=startBit;i<=poolSize/blockSize;i+=sizeBit)
     {
         bool notEmpty=false;
-        for(int j=0;j<sizeBit;j++)
+        for(unsigned int j=0;j<sizeBit;j++)
         {
-            if(testBit(i+j)==0)continue;
+            if(testBit(i+j)==0) continue;
             notEmpty=true;
             break;
         }
         if(notEmpty) continue;
         
-        for(int j=0;j<sizeBit;j++) setBit(i+j);
+        for(unsigned int j=0;j<sizeBit;j++) setBit(i+j);
         unsigned int *result=poolBase+i*blockSize/4;
         allocatedBlocks[result]=size;
         return result;
@@ -57,7 +57,7 @@ void ProcessPool::deallocate(unsigned int *ptr)
     unsigned int size =(it->second)/blockSize;
     unsigned int firstBit=(reinterpret_cast<unsigned int>(ptr)-
                            reinterpret_cast<unsigned int>(poolBase))/blockSize;
-    for(int i=firstBit;i<firstBit+size;i++) clearBit(i);
+    for(unsigned int i=firstBit;i<firstBit+size;i++) clearBit(i);
     allocatedBlocks.erase(it);
 }
 
diff --git a/process_pool.h b/miosix/kernel/process_pool.h
similarity index 93%
rename from process_pool.h
rename to miosix/kernel/process_pool.h
index 8b95af8b6e9b5edb210d927708018e784743189c..e21b97df7d75495bf68b7cfcdaa06c5e5dbdde33 100644
--- a/process_pool.h
+++ b/miosix/kernel/process_pool.h
@@ -37,7 +37,7 @@ public:
      * \throws runtime_error in case the requested allocation is invalid,
      * or bad_alloc if out of memory
      */
-    unsigned int *allocate(int size);
+    unsigned int *allocate(unsigned int size);
     
     /**
      * Deallocate a memory block.
@@ -85,9 +85,9 @@ public:
     
     ///This constant specifies the size of the minimum allocatable block,
     ///in bits. So for example 10 is 1KB.
-    static const int blockBits=10;
+    static const unsigned int blockBits=10;
     ///This constant is the the size of the minimum allocatable block, in bytes.
-    static const int blockSize=1<<blockBits;
+    static const unsigned int blockSize=1<<blockBits;
     
 private:
     ProcessPool(const ProcessPool&);
@@ -97,7 +97,7 @@ private:
      * \param bit bit to test, from 0 to poolSize/blockSize
      * \return true if the bit is set
      */
-    bool testBit(int bit)
+    bool testBit(unsigned int bit)
     {
         return (bitmap[bit/(sizeof(unsigned int)*8)] &
             1<<(bit % (sizeof(unsigned int)*8))) ? true : false;
@@ -106,7 +106,7 @@ private:
     /**
      * \param bit bit to set, from 0 to poolSize/blockSize
      */
-    void setBit(int bit)
+    void setBit(unsigned int bit)
     {
         bitmap[(bit/(sizeof(unsigned int)*8))] |= 
             1<<(bit % (sizeof(unsigned int)*8));
@@ -115,7 +115,7 @@ private:
     /**
      * \param bit bit to clear, from 0 to poolSize/blockSize
      */
-    void clearBit(int bit)
+    void clearBit(unsigned int bit)
     {
         bitmap[bit/(sizeof(unsigned int)*8)] &= 
             ~(1<<(bit % (sizeof(unsigned int)*8)));