diff --git a/.gitignore b/.gitignore
index d4824dba833fb2ade2ee9ed04723c33fb7eacda1..4632339bc3d2f11741370a23d7b05d76f52b776a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ main.hex
 main.map
 *.o
 *.a
+*.d
 
 # Exclude Mac OS X temporary
 ._*
diff --git a/Makefile b/Makefile
index 6c8092c395ce60ea16c806f71d2a1011ae067d4a..32c0a7af5cea447d8e95b2b210bb17522adbdf69 100644
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ SUBDIRS := miosix
 ## List here your source files (both .s, .c and .cpp)
 ##
 SRC :=                                  \
-main.cpp
+miosix/_tools/testsuite/testsuite.cpp
 
 ##
 ## List here additional static libraries with relative path
@@ -40,6 +40,7 @@ CFLAGS    := $(CFLAGS_BASE)   -I. -Imiosix -Imiosix/arch/common \
              -Imiosix/$(ARCH_INC) -Imiosix/$(BOARD_INC) $(INCLUDE_DIRS)
 AFLAGS    := $(AFLAGS_BASE)
 LFLAGS    := $(LFLAGS_BASE)
+DFLAGS    := -MMD -MP
 
 LINK_LIBS := $(LIBS) -L./miosix -Wl,--start-group -lmiosix -lstdc++ -lc -lm \
     -lgcc -Wl,--end-group
@@ -62,7 +63,7 @@ clean-recursive:
 	done
 
 clean-topdir:
-	-rm $(OBJ) main.elf main.hex main.bin main.map
+	-rm $(OBJ) main.elf main.hex main.bin main.map $(OBJ:.o=.d)
 
 main: main.elf
 	$(CP) -O ihex   main.elf main.hex
@@ -77,7 +78,10 @@ main.elf: $(OBJ) miosix/libmiosix.a
 	$(AS) $(AFLAGS) $< -o $@
 
 %.o : %.c
-	$(CC) $(CFLAGS) $< -o $@
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
 
 %.o : %.cpp
-	$(CXX) $(CXXFLAGS) $< -o $@
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/app_template/Makefile b/app_template/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..4fddaa319429061ddebc665eef22f841d1318480
--- /dev/null
+++ b/app_template/Makefile
@@ -0,0 +1,48 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,main.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+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=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i main.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h
+
+clean:
+	-rm $(OBJ) crt0.o main.elf main.map main.txt $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/app_template/crt0.s b/app_template/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..d02fababb9ede48c3deac13b165ed7dfc7eda7a6
--- /dev/null
+++ b/app_template/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * seek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+*/
+.section .text.seek
+.global seek
+.type seek, %function
+seek:
+	movs r3, #8
+	svc 0
+	bx lr
+
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/app_template/main.c b/app_template/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..0b36ae8a7f354101c0e5a9559ea0136e8a8496eb
--- /dev/null
+++ b/app_template/main.c
@@ -0,0 +1,97 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int mystrlen(const char *s)
+{
+	int result=0;
+	while(*s++) result++;
+	return result;
+}
+
+int main()
+{
+	int i = 0;
+	static const char str[]="Test application:\n0=divzero\n1=sleep 5s\n2=exit\n3=bkpt\n4=dangling\n5=open\n6=system\n";
+	static const char str2[]="Unexpected command\n";
+	static const char okMsg[] = "Everything's shiny, Cap'n\n";
+
+	for(;;)
+	{
+		char result[100];
+		write(1,str,mystrlen(str));
+		int len=read(0,result,sizeof(result));
+		if(len<1) continue;
+		int i=10/(int)(result[0]-'0');
+		unsigned int *p=(unsigned int *)0xc0000000;
+		
+		int fp = 0;
+		
+		switch(result[0])
+		{
+			case '0':
+				usleep(i);
+				break;
+			case '1':
+				usleep(5000000);
+				break;
+			case '2':
+				return 0;
+			case '3':
+				asm volatile("bkpt");
+				break;
+			case '4':
+				usleep(*p);
+				break;
+			case '5':
+				fp = open("/test.txt", O_RDWR|O_TRUNC, 0);
+				
+				if(fp != -1){
+					write(1, "File opened\n", 12);
+					int check = 0;
+					
+					if(write(fp, "ciao", 4) == 4){
+						write(1, "Write ok\n", 9);
+						check |= 0x01;
+					}
+				
+					//close(fp);
+					//fp = open("/test.txt", O_RDWR, 0);
+					seek(fp, SEEK_SET, 0);
+					
+					if(write(fp, "123", 3) == 3){
+						write(1, "Write ok\n", 9);
+						check |= 0x01;
+					}
+					
+					seek(fp, SEEK_SET, 0);
+					
+					if(read(fp, result, 100) == 4){
+						write(1, "Read ok\n", 8);
+						check |= 0x02;
+					}
+					
+					if(close(fp) == 0){
+						write(1, "Close ok\n", 9);
+						check |= 0x04;
+					}
+					
+					if(check == 0x07)
+						write(1, okMsg, mystrlen(okMsg));
+				}
+				 
+				
+				break;
+			case '6':
+				system("test");
+				break;
+			default:
+				write(1,str2,mystrlen(str2));
+		}
+	}
+}
diff --git a/app_template/miosix.ld b/app_template/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/app_template/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/app_template/prog3.h b/app_template/prog3.h
new file mode 100644
index 0000000000000000000000000000000000000000..8cbd169379242039a9aa79da18fa850558e839a7
--- /dev/null
+++ b/app_template/prog3.h
@@ -0,0 +1,81 @@
+const unsigned char __attribute__((aligned(8))) main_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0xf2, 0x01, 0x00, 0x00,
+  0xf2, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x90, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x9c, 0x02, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0xde, 0xf8, 0x2d, 0xe9, 0xf0, 0x4d, 0xdf, 0xf8, 0x90, 0x81,
+  0x64, 0x4f, 0xdf, 0xf8, 0x94, 0xa1, 0xdf, 0xf8, 0x94, 0xb1, 0x9c, 0xb0,
+  0x64, 0x4d, 0x03, 0xae, 0xc8, 0x44, 0x4f, 0x44, 0xca, 0x44, 0xcb, 0x44,
+  0x09, 0xeb, 0x05, 0x03, 0x00, 0x22, 0x13, 0xf8, 0x01, 0x4f, 0x01, 0x32,
+  0x00, 0x2c, 0xfa, 0xd1, 0x09, 0xeb, 0x05, 0x01, 0x01, 0x20, 0x00, 0xf0,
+  0xcf, 0xf8, 0x64, 0x22, 0x20, 0x46, 0x31, 0x46, 0x00, 0xf0, 0xcd, 0xf8,
+  0x00, 0x28, 0xeb, 0xdd, 0x9d, 0xf8, 0x0c, 0x30, 0x30, 0x3b, 0x06, 0x2b,
+  0x75, 0xd8, 0xdf, 0xe8, 0x03, 0xf0, 0x6d, 0x66, 0x62, 0x60, 0x5a, 0x08,
+  0x04, 0x00, 0x40, 0x46, 0x00, 0xf0, 0xb7, 0xf8, 0xdc, 0xe7, 0x00, 0x22,
+  0x38, 0x46, 0x40, 0xf2, 0x02, 0x41, 0x00, 0xf0, 0xa7, 0xf8, 0xb0, 0xf1,
+  0xff, 0x3f, 0x04, 0x46, 0xd2, 0xd0, 0x0c, 0x22, 0x01, 0x20, 0x51, 0x46,
+  0x00, 0xf0, 0xaa, 0xf8, 0x04, 0x22, 0x20, 0x46, 0x59, 0x46, 0x00, 0xf0,
+  0xa5, 0xf8, 0x04, 0x28, 0x65, 0xd0, 0x00, 0x21, 0x01, 0x91, 0x00, 0x21,
+  0x0a, 0x46, 0x20, 0x46, 0x00, 0xf0, 0x96, 0xf8, 0x42, 0x49, 0x03, 0x22,
+  0x20, 0x46, 0x49, 0x44, 0x00, 0xf0, 0x96, 0xf8, 0x03, 0x28, 0x6a, 0xd0,
+  0x00, 0x22, 0x11, 0x46, 0x20, 0x46, 0x00, 0xf0, 0x89, 0xf8, 0x64, 0x22,
+  0x20, 0x46, 0x31, 0x46, 0x00, 0xf0, 0x8d, 0xf8, 0x04, 0x28, 0x53, 0xd0,
+  0x20, 0x46, 0x00, 0xf0, 0x7c, 0xf8, 0x04, 0x46, 0x00, 0x28, 0xa5, 0xd1,
+  0x36, 0x49, 0x01, 0x20, 0x49, 0x44, 0x09, 0x22, 0x00, 0xf0, 0x7c, 0xf8,
+  0x01, 0x99, 0x41, 0xf0, 0x04, 0x03, 0x07, 0x2b, 0x9a, 0xd1, 0x09, 0xeb,
+  0x05, 0x03, 0x54, 0x33, 0x22, 0x46, 0x13, 0xf8, 0x01, 0x1f, 0x01, 0x32,
+  0x00, 0x29, 0xfa, 0xd1, 0x09, 0xeb, 0x05, 0x01, 0x54, 0x31, 0x01, 0x20,
+  0x00, 0xf0, 0x68, 0xf8, 0x8a, 0xe7, 0x4f, 0xf0, 0x40, 0x43, 0x18, 0x68,
+  0x00, 0xf0, 0x68, 0xf8, 0x84, 0xe7, 0x00, 0xbe, 0x82, 0xe7, 0x00, 0x20,
+  0x1c, 0xb0, 0xbd, 0xe8, 0xf0, 0x8d, 0x44, 0xf6, 0x40, 0x30, 0xc0, 0xf2,
+  0x4c, 0x00, 0x00, 0xf0, 0x5b, 0xf8, 0x77, 0xe7, 0x00, 0x23, 0x0a, 0x20,
+  0x90, 0xfb, 0xf3, 0xf0, 0x00, 0xf0, 0x54, 0xf8, 0x70, 0xe7, 0x09, 0xeb,
+  0x05, 0x03, 0x70, 0x33, 0x00, 0x22, 0x13, 0xf8, 0x01, 0x1f, 0x01, 0x32,
+  0x00, 0x29, 0xfa, 0xd1, 0x09, 0xeb, 0x05, 0x01, 0x70, 0x31, 0x01, 0x20,
+  0x00, 0xf0, 0x3e, 0xf8, 0x60, 0xe7, 0x15, 0x49, 0x01, 0x20, 0x49, 0x44,
+  0x09, 0x22, 0x00, 0xf0, 0x37, 0xf8, 0x01, 0x23, 0x01, 0x93, 0x92, 0xe7,
+  0x11, 0x49, 0x01, 0x20, 0x49, 0x44, 0x08, 0x22, 0x00, 0xf0, 0x2e, 0xf8,
+  0x01, 0x9b, 0x43, 0xf0, 0x02, 0x03, 0x01, 0x93, 0xa0, 0xe7, 0x0b, 0x49,
+  0x09, 0x22, 0x01, 0x20, 0x49, 0x44, 0x00, 0xf0, 0x23, 0xf8, 0x01, 0x22,
+  0x01, 0x92, 0x8b, 0xe7, 0x08, 0x01, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00,
+  0xc8, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
+  0xec, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+  0xf0, 0x00, 0x00, 0x00, 0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf,
+  0x70, 0x47, 0x07, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x08, 0x23, 0x00, 0xdf,
+  0x70, 0x47, 0x09, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x03, 0x23, 0x00, 0xdf,
+  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, 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, 0x54, 0x65, 0x73, 0x74, 0x20, 0x61, 0x70, 0x70,
+  0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x0a, 0x30, 0x3d,
+  0x64, 0x69, 0x76, 0x7a, 0x65, 0x72, 0x6f, 0x0a, 0x31, 0x3d, 0x73, 0x6c,
+  0x65, 0x65, 0x70, 0x20, 0x35, 0x73, 0x0a, 0x32, 0x3d, 0x65, 0x78, 0x69,
+  0x74, 0x0a, 0x33, 0x3d, 0x62, 0x6b, 0x70, 0x74, 0x0a, 0x34, 0x3d, 0x64,
+  0x61, 0x6e, 0x67, 0x6c, 0x69, 0x6e, 0x67, 0x0a, 0x35, 0x3d, 0x6f, 0x70,
+  0x65, 0x6e, 0x0a, 0x36, 0x3d, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x0a,
+  0x00, 0x00, 0x00, 0x00, 0x45, 0x76, 0x65, 0x72, 0x79, 0x74, 0x68, 0x69,
+  0x6e, 0x67, 0x27, 0x73, 0x20, 0x73, 0x68, 0x69, 0x6e, 0x79, 0x2c, 0x20,
+  0x43, 0x61, 0x70, 0x27, 0x6e, 0x0a, 0x00, 0x00, 0x55, 0x6e, 0x65, 0x78,
+  0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
+  0x6e, 0x64, 0x0a, 0x00, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x78,
+  0x74, 0x00, 0x00, 0x00, 0x46, 0x69, 0x6c, 0x65, 0x20, 0x6f, 0x70, 0x65,
+  0x6e, 0x65, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x63, 0x69, 0x61, 0x6f,
+  0x00, 0x00, 0x00, 0x00, 0x57, 0x72, 0x69, 0x74, 0x65, 0x20, 0x6f, 0x6b,
+  0x0a, 0x00, 0x00, 0x00, 0x31, 0x32, 0x33, 0x00, 0x52, 0x65, 0x61, 0x64,
+  0x20, 0x6f, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x43, 0x6c, 0x6f, 0x73,
+  0x65, 0x20, 0x6f, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x74, 0x65, 0x73, 0x74,
+  0x00, 0x00, 0x00, 0x00
+};
+unsigned int main_elf_len = 928;
diff --git a/app_template_withlibs/Makefile b/app_template_withlibs/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..05bd567d879dc0630cedcc63360e2a35a0840ead
--- /dev/null
+++ b/app_template_withlibs/Makefile
@@ -0,0 +1,52 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c \
+syscallfuffa.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,main.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+# LFLAGS   := -mcpu=cortex-m3 -mthumb -fpie -msingle-pic-base \
+#             -Wl,--gc-sections,-Map,main.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+#             -O2 -nostdlib
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o main.elf $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  main.elf
+	@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:
+	-rm $(OBJ) crt0.o main.elf main.map $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/app_template_withlibs/crt0.s b/app_template_withlibs/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..2eba4bfad53dbe7d82a56e331d9c2b630a44dff7
--- /dev/null
+++ b/app_template_withlibs/crt0.s
@@ -0,0 +1,77 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/app_template_withlibs/main.c b/app_template_withlibs/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..57197b70987ae29d745ee83adf8563101cc52ccb
--- /dev/null
+++ b/app_template_withlibs/main.c
@@ -0,0 +1,39 @@
+
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+	printf("hello world %d\n",25);
+	static const char str[]="0=divzero 1=sleep 5s, 2=exit 3=bkpt 4=dangling\n";
+	static const char str2[]="Unexpected command\n";
+	for(;;)
+	{
+		char result[100];
+		write(1,str,strlen(str));
+		int len=read(0,result,sizeof(result));
+		if(len<1) continue;
+		int i=10/(int)(result[0]-'0');
+		unsigned int *p=(unsigned int *)0xc0000000;
+		switch(result[0])
+		{
+			case '0':
+				usleep(i);
+				break;
+			case '1':
+				usleep(5000000);
+				break;
+			case '2':
+				return 0;
+			case '3':
+				asm volatile("bkpt");
+				break;
+			case '4':
+				usleep(*p);
+				break;
+			default:
+				write(1,str2,strlen(str2));
+		}
+	}
+}
diff --git a/app_template_withlibs/miosix.ld b/app_template_withlibs/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..0b86aaf7afcbf0826cd7e60427f20b38b270696e
--- /dev/null
+++ b/app_template_withlibs/miosix.ld
@@ -0,0 +1,77 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    }
+    __exidx_end = .;
+
+    _end = .;
+    PROVIDE(end = .);
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+        *(.debug*)
+    }
+}
diff --git a/app_template_withlibs/prog3.h b/app_template_withlibs/prog3.h
new file mode 100644
index 0000000000000000000000000000000000000000..8855c4f26cea21ab280c4ea7bc96cfa06f7d8860
--- /dev/null
+++ b/app_template_withlibs/prog3.h
@@ -0,0 +1,40 @@
+const unsigned char __attribute__((aligned(8))) main_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00,
+  0x9e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x38, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x44, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x40, 0xf8, 0x70, 0xb5, 0x1d, 0x4e, 0x1d, 0x4c, 0x7e, 0x44,
+  0x9a, 0xb0, 0x7c, 0x44, 0x30, 0x36, 0x4f, 0xf0, 0x40, 0x45, 0x2f, 0x22,
+  0x21, 0x46, 0x01, 0x20, 0x00, 0xf0, 0x34, 0xf8, 0x64, 0x22, 0x00, 0x20,
+  0x01, 0xa9, 0x00, 0xf0, 0x32, 0xf8, 0x00, 0x28, 0xf3, 0xdd, 0x9d, 0xf8,
+  0x04, 0x30, 0x30, 0x3b, 0x04, 0x2b, 0x1b, 0xd8, 0xdf, 0xe8, 0x03, 0xf0,
+  0x13, 0x0c, 0x09, 0x07, 0x03, 0x00, 0x28, 0x68, 0x00, 0xf0, 0x26, 0xf8,
+  0xe5, 0xe7, 0x00, 0xbe, 0xe3, 0xe7, 0x00, 0x20, 0x1a, 0xb0, 0x70, 0xbd,
+  0x44, 0xf6, 0x40, 0x30, 0xc0, 0xf2, 0x4c, 0x00, 0x00, 0xf0, 0x1a, 0xf8,
+  0xd9, 0xe7, 0x00, 0x23, 0x0a, 0x20, 0x90, 0xfb, 0xf3, 0xf0, 0x00, 0xf0,
+  0x13, 0xf8, 0xd2, 0xe7, 0x01, 0x20, 0x31, 0x46, 0x13, 0x22, 0x00, 0xf0,
+  0x07, 0xf8, 0xcc, 0xe7, 0x8e, 0xff, 0xff, 0x0f, 0x8a, 0xff, 0xff, 0x0f,
+  0x02, 0x23, 0x00, 0xdf, 0x03, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x04, 0x23,
+  0x00, 0xdf, 0x70, 0x47, 0x05, 0x23, 0x00, 0xdf, 0x70, 0x47, 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, 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, 0x6f, 0x20, 0x31, 0x3d, 0x73, 0x6c, 0x65, 0x65,
+  0x70, 0x20, 0x35, 0x73, 0x2c, 0x20, 0x32, 0x3d, 0x65, 0x78, 0x69, 0x74,
+  0x20, 0x33, 0x3d, 0x62, 0x6b, 0x70, 0x74, 0x20, 0x34, 0x3d, 0x64, 0x61,
+  0x6e, 0x67, 0x6c, 0x69, 0x6e, 0x67, 0x0a, 0x00, 0x55, 0x6e, 0x65, 0x78,
+  0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
+  0x6e, 0x64, 0x0a, 0x00
+};
+unsigned int main_elf_len = 436;
diff --git a/app_template_withlibs/syscallfuffa.c b/app_template_withlibs/syscallfuffa.c
new file mode 100644
index 0000000000000000000000000000000000000000..3c12251f397822722314403fd61edb4ec3cd98e2
--- /dev/null
+++ b/app_template_withlibs/syscallfuffa.c
@@ -0,0 +1,62 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <reent.h>
+#include <sys/times.h>
+#include <sys/stat.h>
+#include <sys/fcntl.h>
+#include <unistd.h>
+
+void pthread_mutex_unlock() {}
+void pthread_mutex_lock() {}
+void pthread_mutex_destroy() {}
+
+int __register_exitproc(int type, void (*fn)(void), void *arg, void *d) { return 0; }
+void __call_exitprocs(int code, void *d) {}
+
+void *__dso_handle=(void*) &__dso_handle;
+
+void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr) { return (void*)-1; }
+void __malloc_lock() {}
+void __malloc_unlock() {}
+int _open_r(struct _reent *ptr, const char *name, int flags, int mode) { return -1; }
+int _close_r(struct _reent *ptr, int fd) { return -1; }
+
+int _write(int fd, const void *buf, size_t cnt)
+{
+    return write(fd,buf,cnt);
+}
+
+int _write_r(struct _reent *ptr, int fd, const void *buf, size_t cnt)
+{
+    return write(fd,buf,cnt);
+}
+
+int _read(int fd, void *buf, size_t cnt)
+{
+    return read(fd,buf,cnt);
+}
+
+int _read_r(struct _reent *ptr, int fd, void *buf, size_t cnt)
+{
+    return read(fd,buf,cnt);
+}
+
+off_t _lseek(int fd, off_t pos, int whence) { return -1; }
+off_t _lseek_r(struct _reent *ptr, int fd, off_t pos, int whence) { return -1; }
+int _fstat(int fd, struct stat *pstat) { return -1; }
+int _fstat_r(struct _reent *ptr, int fd, struct stat *pstat) { return -1; }
+int _stat_r(struct _reent *ptr, const char *file, struct stat *pstat) { return -1; }
+int isatty(int fd) { return -1; }
+int _isatty(int fd) { return -1; }
+int mkdir(const char *path, mode_t mode) { return -1; }
+int _unlink_r(struct _reent *ptr, const char *file) { return -1; }
+clock_t _times_r(struct _reent *ptr, struct tms *tim) { return -1; }
+int _link_r(struct _reent *ptr, const char *f_old, const char *f_new) { return -1; }
+int _kill(int pid, int sig) { return -1; }
+int _kill_r(struct _reent* ptr, int pid, int sig) { return -1; }
+int _getpid() { return 1; }
+int _getpid_r(struct _reent* ptr) { return 1; }
+int _fork_r(struct _reent *ptr) { return -1; }
+int _wait_r(struct _reent *ptr, int *status) { return -1; }
diff --git a/main_processes.cpp b/main_processes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c11b63e18d905dcd0f432f16fefc170a170fcbfb
--- /dev/null
+++ b/main_processes.cpp
@@ -0,0 +1,52 @@
+
+#include <cstdio>
+#include <sys/wait.h>
+#include <signal.h>
+#include "miosix.h"
+#include "kernel/process.h"
+#include "kernel/SystemMap.h"
+
+#include "app_template/prog3.h"
+
+using namespace std;
+using namespace miosix;
+
+void ledThread(void *)
+{
+    for(;;)
+    {
+        ledOn();
+        Thread::sleep(200);
+        ledOff();
+        Thread::sleep(200);
+    }
+}
+
+int main()
+{
+    Thread::create(ledThread,STACK_MIN);
+	
+	//SystemMap::instance().addElfProgram("test", reinterpret_cast<const unsigned int*>(test_elf), test_elf_len);
+	
+	//iprintf("SystemMap::size: %d\n", SystemMap::instance().getElfCount());
+	//std::pair<const unsigned int*, unsigned int> res = SystemMap::instance().getElfProgram("test");
+	//iprintf("SystemMap test entry size: %X %d\n", res.first, res.second);
+    
+    ElfProgram prog(reinterpret_cast<const unsigned int*>(main_elf),main_elf_len);
+    for(int i=0;;i++)
+    {
+        getchar();
+        pid_t child=Process::create(prog);
+        int ec;
+        pid_t pid;
+        if(i%2==0) pid=Process::wait(&ec);
+        else pid=Process::waitpid(child,&ec,0);
+        iprintf("Process %d terminated\n",pid);
+        if(WIFEXITED(ec))
+        {
+            iprintf("Exit code is %d\n",WEXITSTATUS(ec));
+        } else if(WIFSIGNALED(ec)) {
+            if(WTERMSIG(ec)==SIGSEGV) iprintf("Process segfaulted\n");
+        }
+    }
+}
diff --git a/miosix/Makefile b/miosix/Makefile
index 344ece19bbab8a130d8c0be8f50400266b26feba..f66f581604f5d97ae6ff9e02068d66fcfcb81809 100644
--- a/miosix/Makefile
+++ b/miosix/Makefile
@@ -15,6 +15,10 @@ kernel/sync.cpp                                                            \
 kernel/error.cpp                                                           \
 kernel/pthread.cpp                                                         \
 kernel/stage_2_boot.cpp                                                    \
+kernel/elf_program.cpp                                                     \
+kernel/process.cpp                                                         \
+kernel/process_pool.cpp                                                    \
+kernel/SystemMap.cpp                                                       \
 kernel/scheduler/priority/priority_scheduler.cpp                           \
 kernel/scheduler/control/control_scheduler.cpp                             \
 kernel/scheduler/edf/edf_scheduler.cpp                                     \
@@ -52,6 +56,7 @@ CXXFLAGS := $(CXXFLAGS_BASE) -I. -Iarch/common -I$(ARCH_INC) -I$(BOARD_INC) \
 CFLAGS   := $(CFLAGS_BASE)   -I. -Iarch/common -I$(ARCH_INC) -I$(BOARD_INC) \
 	    -DCOMPILING_MIOSIX
 AFLAGS   := $(AFLAGS_BASE)
+DFLAGS    := -MMD -MP
 
 ## Build libmiosix.a and stage_1_boot.o (whose path is in BOOT_FILE)
 ## The file stage_1_boot.o is compiled separately because
@@ -61,13 +66,16 @@ all: $(OBJ) $(BOOT_FILE)
 	$(AR) rcs libmiosix.a $(OBJ)
 
 clean:
-	rm $(OBJ) $(BOOT_FILE) libmiosix.a
+	-rm $(OBJ) $(BOOT_FILE) libmiosix.a $(OBJ:.o=.d) $(BOOT_FILE:.o=.d)
 
 %.o: %.s
 	$(AS) $(AFLAGS) $< -o $@
 
 %.o : %.c
-	$(CC) $(CFLAGS) $< -o $@
+	$(CC)  $(DFLAGS) $(CFLAGS) $< -o $@
 
 %.o : %.cpp
-	$(CXX) $(CXXFLAGS) $< -o $@
+	$(CXX)  $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_examples/sad_trombone/Makefile b/miosix/_examples/sad_trombone/Makefile
index 9b484b4da268f9aa561a5e9c3f78b365117e79e3..30df07af82361dbefad47b3a59a9d31f159183bd 100644
--- a/miosix/_examples/sad_trombone/Makefile
+++ b/miosix/_examples/sad_trombone/Makefile
@@ -40,6 +40,7 @@ CFLAGS    := $(CFLAGS_BASE)   -I. -Imiosix -Imiosix/arch/common \
              -Imiosix/$(ARCH_INC) -Imiosix/$(BOARD_INC) $(INCLUDE_DIRS)
 AFLAGS    := $(AFLAGS_BASE)
 LFLAGS    := $(LFLAGS_BASE)
+DFLAGS    := -MMD -MP
 
 LINK_LIBS := $(LIBS) -L./miosix -Wl,--start-group -lmiosix -lstdc++ -lc -lm \
     -lgcc -Wl,--end-group
@@ -62,7 +63,7 @@ clean-recursive:
 	done
 
 clean-topdir:
-	-rm $(OBJ) main.elf main.hex main.bin main.map
+	-rm $(OBJ) main.elf main.hex main.bin main.map $(OBJ:.o=.d)
 
 main: main.elf
 	$(CP) -O ihex   main.elf main.hex
@@ -77,7 +78,10 @@ main.elf: $(OBJ) miosix/libmiosix.a
 	$(AS) $(AFLAGS) $< -o $@
 
 %.o : %.c
-	$(CC) $(CFLAGS) $< -o $@
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
 
 %.o : %.cpp
-	$(CXX) $(CXXFLAGS) $< -o $@
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_tools/bootloaders/stm32/pc_loader/pc_loader b/miosix/_tools/bootloaders/stm32/pc_loader/pc_loader
old mode 100644
new mode 100755
diff --git a/miosix/_tools/compiler/cleanup.sh b/miosix/_tools/compiler/cleanup.sh
old mode 100644
new mode 100755
diff --git a/miosix/_tools/compiler/install-script.sh b/miosix/_tools/compiler/install-script.sh
index 92cf02460bfa63b540141832f782469fd29107b8..4b1d710fd53a4008fca27e844115a278f080aef2 100755
--- a/miosix/_tools/compiler/install-script.sh
+++ b/miosix/_tools/compiler/install-script.sh
@@ -236,7 +236,15 @@ $SUDO make install 2>../log/n.txt			|| quit ":: Error installing gdb"
 
 cd ..
 
-# Last thing, remove this since it's not necessary
+#
+# Part 10: install the postlinker
+#
+cd mx-postlinker
+make
+$SUDO make install INSTALL_DIR=$INSTALL_DIR/arm-miosix-eabi/bin
+cd ..
+
+# Last thing, remove this since its name is not arm-miosix-eabi-
 $SUDO rm $INSTALL_DIR/arm-miosix-eabi/bin/arm-miosix-eabi-$GCC
 
 # If sudo not an empty variable, make symlinks to /usr/bin
diff --git a/miosix/_tools/compiler/uninstall.sh b/miosix/_tools/compiler/uninstall.sh
old mode 100644
new mode 100755
diff --git a/miosix/_tools/testsuite/Readme.txt b/miosix/_tools/testsuite/Readme.txt
index e3305737b84bf0ba8ce7521de3db6b051e22f70a..f5682d38a09e91c2b4e6f10c696e10d818210ff5 100644
--- a/miosix/_tools/testsuite/Readme.txt
+++ b/miosix/_tools/testsuite/Readme.txt
@@ -1,5 +1,9 @@
 
-To run the testsuite, modify the Makefile from 
+To run the testsuite:
+1) Run "build.sh" in the mpu_testsuite directory,
+2) Run "build.sh testsuite" in the syscall_testsuite directory,
+3) Copy testsuite.cpp from this directory into the top
+   level directory and modify the Makefile, from
 
 SRC :=                                  \
 main.cpp
@@ -7,4 +11,8 @@ main.cpp
 to
 
 SRC :=                                  \
-miosix/_tools/testsuite/testsuite.cpp
\ No newline at end of file
+testsuite.cpp
+
+Run "cleanup.sh" from mpu_testsuite directory to clean compilation files.
+
+For more information, see the Readme.txt files in the subdirectories.
\ No newline at end of file
diff --git a/miosix/_tools/testsuite/elf_testsuite/Readme.txt b/miosix/_tools/testsuite/elf_testsuite/Readme.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0e22456e1c2d2d78199e8b1ba423aa5c56762130
--- /dev/null
+++ b/miosix/_tools/testsuite/elf_testsuite/Readme.txt
@@ -0,0 +1,7 @@
+aelf1 : Stack size set to 128 (stack size must be greater than MIN_PROCESS_STACK_SIZE [256])
+aelf2 : Ram size set to 65535 (ram size must be less than MAX_PROCESS_IMAGE_SIZE [64*1024])
+aelf3 : Stack size set to 1945 (stack size must be multiple of 4)
+aelf4 : Ram size set to 14745 (ram size must be multiple of 4)
+aelf5 : Ram size set to 200 (ram size must be greater than BLOCK_SIZE [1024])
+aelf6 : Stack size set to 32768 (data segment size + stack size must be less than ram size)
+aelf7 : Stack size set to 65535 (stack size must be less than MAX_PROCESS_IMAGE_SIZE [64*1024])
\ No newline at end of file
diff --git a/miosix/_tools/testsuite/elf_testsuite/aelf1.h b/miosix/_tools/testsuite/elf_testsuite/aelf1.h
new file mode 100644
index 0000000000000000000000000000000000000000..66a2d790c6b0e328937e09a56af9fd344b3fc875
--- /dev/null
+++ b/miosix/_tools/testsuite/elf_testsuite/aelf1.h
@@ -0,0 +1,22 @@
+const unsigned char __attribute__((aligned(8))) aelf1[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xb4, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x02, 0xf8, 0x00, 0x20, 0x70, 0x47, 0x02, 0x23, 0x00, 0xdf,
+  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, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00,
+  0x4d, 0x69, 0x6f, 0x73, 0x69, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+unsigned int aelf1_len = 220;
diff --git a/miosix/_tools/testsuite/elf_testsuite/aelf2.h b/miosix/_tools/testsuite/elf_testsuite/aelf2.h
new file mode 100644
index 0000000000000000000000000000000000000000..9de6257fa9314faf6a0fe684da1792954eb13243
--- /dev/null
+++ b/miosix/_tools/testsuite/elf_testsuite/aelf2.h
@@ -0,0 +1,22 @@
+const unsigned char __attribute__((aligned(8))) aelf2[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xb4, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x02, 0xf8, 0x00, 0x20, 0x70, 0x47, 0x02, 0x23, 0x00, 0xdf,
+  0x0c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0xFF, 0xFF, 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
+};
+unsigned int aelf2_len = 220;
diff --git a/miosix/_tools/testsuite/elf_testsuite/aelf3.h b/miosix/_tools/testsuite/elf_testsuite/aelf3.h
new file mode 100644
index 0000000000000000000000000000000000000000..e15754a4020434a385d23660ba0baa7badfb4197
--- /dev/null
+++ b/miosix/_tools/testsuite/elf_testsuite/aelf3.h
@@ -0,0 +1,22 @@
+const unsigned char __attribute__((aligned(8))) aelf3[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xb4, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x02, 0xf8, 0x00, 0x20, 0x70, 0x47, 0x02, 0x23, 0x00, 0xdf,
+  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, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x99, 0x79, 0x00, 0x00,
+  0x4d, 0x69, 0x6f, 0x73, 0x69, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+unsigned int aelf3_len = 220;
diff --git a/miosix/_tools/testsuite/elf_testsuite/aelf4.h b/miosix/_tools/testsuite/elf_testsuite/aelf4.h
new file mode 100644
index 0000000000000000000000000000000000000000..6a93936e62b9cf38a0905f019af09353849587a6
--- /dev/null
+++ b/miosix/_tools/testsuite/elf_testsuite/aelf4.h
@@ -0,0 +1,22 @@
+const unsigned char __attribute__((aligned(8))) aelf4[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xb4, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x02, 0xf8, 0x00, 0x20, 0x70, 0x47, 0x02, 0x23, 0x00, 0xdf,
+  0x0c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x99, 0x39, 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
+};
+unsigned int aelf4_len = 220;
diff --git a/miosix/_tools/testsuite/elf_testsuite/aelf5.h b/miosix/_tools/testsuite/elf_testsuite/aelf5.h
new file mode 100644
index 0000000000000000000000000000000000000000..6bab559e612ec37ed4613dfaf2e21e1981959b87
--- /dev/null
+++ b/miosix/_tools/testsuite/elf_testsuite/aelf5.h
@@ -0,0 +1,22 @@
+const unsigned char __attribute__((aligned(8))) aelf5[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xb4, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x02, 0xf8, 0x00, 0x20, 0x70, 0x47, 0x02, 0x23, 0x00, 0xdf,
+  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, 0x02, 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
+};
+unsigned int aelf5_len = 220;
diff --git a/miosix/_tools/testsuite/elf_testsuite/aelf6.h b/miosix/_tools/testsuite/elf_testsuite/aelf6.h
new file mode 100644
index 0000000000000000000000000000000000000000..7ab0ec68916886c90580713201f01ade80f1735e
--- /dev/null
+++ b/miosix/_tools/testsuite/elf_testsuite/aelf6.h
@@ -0,0 +1,22 @@
+const unsigned char __attribute__((aligned(8))) aelf6[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xb4, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x02, 0xf8, 0x00, 0x20, 0x70, 0x47, 0x02, 0x23, 0x00, 0xdf,
+  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, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00,
+  0x4d, 0x69, 0x6f, 0x73, 0x69, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+unsigned int aelf6_len = 220;
diff --git a/miosix/_tools/testsuite/elf_testsuite/aelf7.h b/miosix/_tools/testsuite/elf_testsuite/aelf7.h
new file mode 100644
index 0000000000000000000000000000000000000000..257d4cb8bc7e5a4feda1582b5577b9fc6c2ca101
--- /dev/null
+++ b/miosix/_tools/testsuite/elf_testsuite/aelf7.h
@@ -0,0 +1,22 @@
+const unsigned char __attribute__((aligned(8))) aelf7[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xb4, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x02, 0xf8, 0x00, 0x20, 0x70, 0x47, 0x02, 0x23, 0x00, 0xdf,
+  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, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0xFF, 0xFF, 0x00, 0x00,
+  0x4d, 0x69, 0x6f, 0x73, 0x69, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00
+};
+unsigned int aelf7_len = 220;
diff --git a/miosix/_tools/testsuite/elf_testsuite/includes.h b/miosix/_tools/testsuite/elf_testsuite/includes.h
new file mode 100644
index 0000000000000000000000000000000000000000..255fcd80282b4cbfc817abdf6705293fef24d7ee
--- /dev/null
+++ b/miosix/_tools/testsuite/elf_testsuite/includes.h
@@ -0,0 +1,10 @@
+#ifndef _APP_ELF_TESTS_
+#define _APP_ELF_TESTS_
+#include "miosix/testsuite/elf_testsuite/aelf1.h"
+#include "miosix/testsuite/elf_testsuite/aelf2.h"
+#include "miosix/testsuite/elf_testsuite/aelf3.h"
+#include "miosix/testsuite/elf_testsuite/aelf4.h"
+#include "miosix/testsuite/elf_testsuite/aelf5.h"
+#include "miosix/testsuite/elf_testsuite/aelf6.h"
+#include "miosix/testsuite/elf_testsuite/aelf7.h"
+#endif //_APP_ELF_TESTS_
diff --git a/miosix/_tools/testsuite/mpu_testsuite/Readme.txt b/miosix/_tools/testsuite/mpu_testsuite/Readme.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e8d740ca809fa0fa69025982e2dabd53385e0f9f
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/Readme.txt
@@ -0,0 +1,14 @@
+
+To run the testsuite, run build.sh in the mpu_apps directory,
+then copy mpu_testsuite.cpp from this directory into the top
+level directory and modify the Makefile, from
+
+SRC :=                                  \
+main.cpp
+
+to
+
+SRC :=                                  \
+mpu_testsuite.cpp
+
+Run cleanup.sh from mpu_apps directory to clean compilation files.
\ No newline at end of file
diff --git a/miosix/_tools/testsuite/mpu_testsuite/build.sh b/miosix/_tools/testsuite/mpu_testsuite/build.sh
new file mode 100644
index 0000000000000000000000000000000000000000..984ccdc6f7536037c32e4938932b5987687f5328
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/build.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+echo > includes.h
+echo "#ifndef _APP_MPU_TESTS_" >> includes.h
+echo "#define _APP_MPU_TESTS_" >> includes.h
+
+for i in *;
+do
+	if test -d $i; then
+		cd $i && make clean && make && cp mpuTest.h "../$i.h" && cd ..
+		echo "#include \"miosix/testsuite/mpu_testsuite/$i.h\"" >> includes.h
+		sed "s/test_elf/$i\_elf/" $i.h -i
+	fi;
+done;
+
+echo "#endif //_APP_MPU_TESTS_" >> includes.h
diff --git a/miosix/_tools/testsuite/mpu_testsuite/cleanup.sh b/miosix/_tools/testsuite/mpu_testsuite/cleanup.sh
new file mode 100644
index 0000000000000000000000000000000000000000..450e08d3c8d68e1ca8d52d2f7fe882cd4b9904ea
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/cleanup.sh
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+rm includes.h
+
+for i in *;
+do
+	if test -d $i; then
+		rm "$i.h"
+		cd $i && make clean && cd ..
+	fi;
+done;
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test1/Makefile b/miosix/_tools/testsuite/mpu_testsuite/test1/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1523e24bde2cb6937bcc985c1c45062d4987cbdc
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test1/Makefile
@@ -0,0 +1,48 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o test.elf $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  test.elf
+	@arm-miosix-eabi-objdump -Dslx test.elf > test.txt
+	@mx-postlinker test.elf --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i test.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > mpuTest.h
+
+clean:
+	-rm $(OBJ) crt0.o test.elf test.map test.txt mpuTest.h $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test1/crt0.s b/miosix/_tools/testsuite/mpu_testsuite/test1/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..7733008e9392ded796006a94a0c1a527a94bfc1a
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test1/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+ 
+.section .text.lseek
+.global lseek
+.type lseek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+*/
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test1/main.c b/miosix/_tools/testsuite/mpu_testsuite/test1/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..36d4f25285da2aac823dc280f630c0d9f4f245d8
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test1/main.c
@@ -0,0 +1,16 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+	// 'address' points to a memory location allocated with ProcessPool
+	// and owned by the kernel. The program tries to write the location.
+	volatile unsigned int *address = 0x64100000;
+	*address = 0xbbbbbbbb;
+	return 0;
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test1/miosix.ld b/miosix/_tools/testsuite/mpu_testsuite/test1/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test1/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test10_1/Makefile b/miosix/_tools/testsuite/mpu_testsuite/test10_1/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1523e24bde2cb6937bcc985c1c45062d4987cbdc
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test10_1/Makefile
@@ -0,0 +1,48 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o test.elf $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  test.elf
+	@arm-miosix-eabi-objdump -Dslx test.elf > test.txt
+	@mx-postlinker test.elf --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i test.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > mpuTest.h
+
+clean:
+	-rm $(OBJ) crt0.o test.elf test.map test.txt mpuTest.h $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test10_1/crt0.s b/miosix/_tools/testsuite/mpu_testsuite/test10_1/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..7733008e9392ded796006a94a0c1a527a94bfc1a
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test10_1/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+ 
+.section .text.lseek
+.global lseek
+.type lseek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+*/
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test10_1/main.c b/miosix/_tools/testsuite/mpu_testsuite/test10_1/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..1ee253fb920330bed3f9675de9d9a9dbf88e8af9
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test10_1/main.c
@@ -0,0 +1,16 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+        // This process goes to sleep for 2 seconds, while the second
+        // process tries to  access the data region of this process.
+        unsigned int i=0;
+        for(i=0; i<5000000; i++)
+        return 0;
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test10_1/miosix.ld b/miosix/_tools/testsuite/mpu_testsuite/test10_1/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test10_1/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test10_2/Makefile b/miosix/_tools/testsuite/mpu_testsuite/test10_2/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1523e24bde2cb6937bcc985c1c45062d4987cbdc
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test10_2/Makefile
@@ -0,0 +1,48 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o test.elf $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  test.elf
+	@arm-miosix-eabi-objdump -Dslx test.elf > test.txt
+	@mx-postlinker test.elf --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i test.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > mpuTest.h
+
+clean:
+	-rm $(OBJ) crt0.o test.elf test.map test.txt mpuTest.h $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test10_2/crt0.s b/miosix/_tools/testsuite/mpu_testsuite/test10_2/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..7733008e9392ded796006a94a0c1a527a94bfc1a
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test10_2/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+ 
+.section .text.lseek
+.global lseek
+.type lseek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+*/
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test10_2/main.c b/miosix/_tools/testsuite/mpu_testsuite/test10_2/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..7f691459bc86affe5c6c061d2d0d941f89e0def9
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test10_2/main.c
@@ -0,0 +1,18 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+	// The process tries to fill almost all the stack with an array
+	// and then tries to save the context by calling a syscall.
+	// With an array of 16344 bytes, there is no fault.
+	volatile unsigned char array[16345];
+	array[0]=1;
+	usleep(2000000);
+	return 0;
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test10_2/miosix.ld b/miosix/_tools/testsuite/mpu_testsuite/test10_2/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test10_2/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test2/Makefile b/miosix/_tools/testsuite/mpu_testsuite/test2/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1523e24bde2cb6937bcc985c1c45062d4987cbdc
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test2/Makefile
@@ -0,0 +1,48 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o test.elf $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  test.elf
+	@arm-miosix-eabi-objdump -Dslx test.elf > test.txt
+	@mx-postlinker test.elf --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i test.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > mpuTest.h
+
+clean:
+	-rm $(OBJ) crt0.o test.elf test.map test.txt mpuTest.h $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test2/crt0.s b/miosix/_tools/testsuite/mpu_testsuite/test2/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..7733008e9392ded796006a94a0c1a527a94bfc1a
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test2/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+ 
+.section .text.lseek
+.global lseek
+.type lseek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+*/
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test2/main.c b/miosix/_tools/testsuite/mpu_testsuite/test2/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..d4bf9153e88f9559d7f670b1d22aff14310b816e
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test2/main.c
@@ -0,0 +1,16 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+	// 'address' points to a memory location allocated with ProcessPool
+	// and owned by the kernel. The program tries to read the location.
+	volatile unsigned int *address = 0x64100200;
+	volatile unsigned int c = *address;
+	return 0;
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test2/miosix.ld b/miosix/_tools/testsuite/mpu_testsuite/test2/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test2/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test3/Makefile b/miosix/_tools/testsuite/mpu_testsuite/test3/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1523e24bde2cb6937bcc985c1c45062d4987cbdc
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test3/Makefile
@@ -0,0 +1,48 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o test.elf $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  test.elf
+	@arm-miosix-eabi-objdump -Dslx test.elf > test.txt
+	@mx-postlinker test.elf --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i test.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > mpuTest.h
+
+clean:
+	-rm $(OBJ) crt0.o test.elf test.map test.txt mpuTest.h $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test3/crt0.s b/miosix/_tools/testsuite/mpu_testsuite/test3/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..7733008e9392ded796006a94a0c1a527a94bfc1a
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test3/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+ 
+.section .text.lseek
+.global lseek
+.type lseek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+*/
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test3/main.c b/miosix/_tools/testsuite/mpu_testsuite/test3/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..93f2819c0c91d7f9ed3d2148cc2204b405c3a5c8
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test3/main.c
@@ -0,0 +1,16 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+	// 'address' points to a memory location allocated and owned by
+	// the kernel. The program tries to write the location.
+	volatile unsigned int *address = 0x63F0FFFF;
+	*address = 0xbbbbbbbb;
+	return 0;
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test3/miosix.ld b/miosix/_tools/testsuite/mpu_testsuite/test3/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test3/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test4/Makefile b/miosix/_tools/testsuite/mpu_testsuite/test4/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1523e24bde2cb6937bcc985c1c45062d4987cbdc
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test4/Makefile
@@ -0,0 +1,48 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o test.elf $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  test.elf
+	@arm-miosix-eabi-objdump -Dslx test.elf > test.txt
+	@mx-postlinker test.elf --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i test.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > mpuTest.h
+
+clean:
+	-rm $(OBJ) crt0.o test.elf test.map test.txt mpuTest.h $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test4/crt0.s b/miosix/_tools/testsuite/mpu_testsuite/test4/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..7733008e9392ded796006a94a0c1a527a94bfc1a
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test4/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+ 
+.section .text.lseek
+.global lseek
+.type lseek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+*/
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test4/main.c b/miosix/_tools/testsuite/mpu_testsuite/test4/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..81c73f92bde85b6f864dfc214ad1eafb33b576ad
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test4/main.c
@@ -0,0 +1,16 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+	// The process tries to allocate an array of size greater than
+	// the available memory and writes to it;
+	volatile unsigned char array[16 * 1024 + 1];
+	array[0] = 0;
+	return 0;
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test4/miosix.ld b/miosix/_tools/testsuite/mpu_testsuite/test4/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test4/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test5/Makefile b/miosix/_tools/testsuite/mpu_testsuite/test5/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1523e24bde2cb6937bcc985c1c45062d4987cbdc
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test5/Makefile
@@ -0,0 +1,48 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o test.elf $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  test.elf
+	@arm-miosix-eabi-objdump -Dslx test.elf > test.txt
+	@mx-postlinker test.elf --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i test.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > mpuTest.h
+
+clean:
+	-rm $(OBJ) crt0.o test.elf test.map test.txt mpuTest.h $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test5/crt0.s b/miosix/_tools/testsuite/mpu_testsuite/test5/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..7733008e9392ded796006a94a0c1a527a94bfc1a
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test5/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+ 
+.section .text.lseek
+.global lseek
+.type lseek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+*/
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test5/main.c b/miosix/_tools/testsuite/mpu_testsuite/test5/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..3ab4d4fc453ef71904c9be6d033e65f792582990
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test5/main.c
@@ -0,0 +1,16 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+	// 'address' points to a memory location inside the code
+	// segment of the program. The program tries to write the location.
+	volatile unsigned int *address = 0x64101000;
+	*address = 0xbbbbbbbb;
+	return 0;
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test5/miosix.ld b/miosix/_tools/testsuite/mpu_testsuite/test5/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test5/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test6/Makefile b/miosix/_tools/testsuite/mpu_testsuite/test6/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1523e24bde2cb6937bcc985c1c45062d4987cbdc
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test6/Makefile
@@ -0,0 +1,48 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o test.elf $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  test.elf
+	@arm-miosix-eabi-objdump -Dslx test.elf > test.txt
+	@mx-postlinker test.elf --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i test.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > mpuTest.h
+
+clean:
+	-rm $(OBJ) crt0.o test.elf test.map test.txt mpuTest.h $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test6/crt0.s b/miosix/_tools/testsuite/mpu_testsuite/test6/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..7733008e9392ded796006a94a0c1a527a94bfc1a
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test6/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+ 
+.section .text.lseek
+.global lseek
+.type lseek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+*/
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test6/main.c b/miosix/_tools/testsuite/mpu_testsuite/test6/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..ed0796b8b92e45c11cb50b74233e482f6f787cc4
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test6/main.c
@@ -0,0 +1,16 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+	// 'address' points to a memory location between the
+	// code segment and the data segment.
+	volatile unsigned int *address = 0x64101404;
+	*address = 0xbbbbbbbb;
+	return 0;
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test6/miosix.ld b/miosix/_tools/testsuite/mpu_testsuite/test6/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test6/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test7/Makefile b/miosix/_tools/testsuite/mpu_testsuite/test7/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1523e24bde2cb6937bcc985c1c45062d4987cbdc
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test7/Makefile
@@ -0,0 +1,48 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o test.elf $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  test.elf
+	@arm-miosix-eabi-objdump -Dslx test.elf > test.txt
+	@mx-postlinker test.elf --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i test.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > mpuTest.h
+
+clean:
+	-rm $(OBJ) crt0.o test.elf test.map test.txt mpuTest.h $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test7/crt0.s b/miosix/_tools/testsuite/mpu_testsuite/test7/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..7733008e9392ded796006a94a0c1a527a94bfc1a
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test7/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+ 
+.section .text.lseek
+.global lseek
+.type lseek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+*/
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test7/includes.h b/miosix/_tools/testsuite/mpu_testsuite/test7/includes.h
new file mode 100644
index 0000000000000000000000000000000000000000..15f9f03434f0e0839fd2fa1b8d47f9152dcdcc62
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test7/includes.h
@@ -0,0 +1,2 @@
+#include "mpu_testsuite/mpu_apps/test7.h"
+#endif //_APP_MPU_TESTS_1_
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test7/main.c b/miosix/_tools/testsuite/mpu_testsuite/test7/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..7f691459bc86affe5c6c061d2d0d941f89e0def9
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test7/main.c
@@ -0,0 +1,18 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+	// The process tries to fill almost all the stack with an array
+	// and then tries to save the context by calling a syscall.
+	// With an array of 16344 bytes, there is no fault.
+	volatile unsigned char array[16345];
+	array[0]=1;
+	usleep(2000000);
+	return 0;
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test7/miosix.ld b/miosix/_tools/testsuite/mpu_testsuite/test7/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test7/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test8_1/Makefile b/miosix/_tools/testsuite/mpu_testsuite/test8_1/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1523e24bde2cb6937bcc985c1c45062d4987cbdc
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test8_1/Makefile
@@ -0,0 +1,48 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o test.elf $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  test.elf
+	@arm-miosix-eabi-objdump -Dslx test.elf > test.txt
+	@mx-postlinker test.elf --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i test.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > mpuTest.h
+
+clean:
+	-rm $(OBJ) crt0.o test.elf test.map test.txt mpuTest.h $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test8_1/crt0.s b/miosix/_tools/testsuite/mpu_testsuite/test8_1/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..7733008e9392ded796006a94a0c1a527a94bfc1a
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test8_1/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+ 
+.section .text.lseek
+.global lseek
+.type lseek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+*/
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test8_1/includes.h b/miosix/_tools/testsuite/mpu_testsuite/test8_1/includes.h
new file mode 100644
index 0000000000000000000000000000000000000000..d9e2fa61fea7aa8d1687bc591fc4c7b74258d600
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test8_1/includes.h
@@ -0,0 +1,2 @@
+#include "mpu_testsuite/mpu_apps/test8_1.h"
+#endif //_APP_MPU_TESTS_1_
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test8_1/main.c b/miosix/_tools/testsuite/mpu_testsuite/test8_1/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..6ad36ce84a30eb1766f5ef37ddf030d746144f68
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test8_1/main.c
@@ -0,0 +1,15 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+	// This process goes to sleep for 2 seconds, while the second
+	// process tries to access the data region of this process.
+	usleep(2000000);
+	return 0;
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test8_1/miosix.ld b/miosix/_tools/testsuite/mpu_testsuite/test8_1/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test8_1/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test8_2/Makefile b/miosix/_tools/testsuite/mpu_testsuite/test8_2/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1523e24bde2cb6937bcc985c1c45062d4987cbdc
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test8_2/Makefile
@@ -0,0 +1,48 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o test.elf $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  test.elf
+	@arm-miosix-eabi-objdump -Dslx test.elf > test.txt
+	@mx-postlinker test.elf --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i test.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > mpuTest.h
+
+clean:
+	-rm $(OBJ) crt0.o test.elf test.map test.txt mpuTest.h $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test8_2/crt0.s b/miosix/_tools/testsuite/mpu_testsuite/test8_2/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..7733008e9392ded796006a94a0c1a527a94bfc1a
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test8_2/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+ 
+.section .text.lseek
+.global lseek
+.type lseek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+*/
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test8_2/main.c b/miosix/_tools/testsuite/mpu_testsuite/test8_2/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..b45aa841b01eb1fd3d646a7d1fd32e6e2f4e804d
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test8_2/main.c
@@ -0,0 +1,16 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+	// 'address' points to a memory location of the program 8.1.
+	// The program tries to write the location.
+	volatile int *address = 0x64104004;
+	*address = 0xbbbbbbbb;
+	return 0;
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test8_2/miosix.ld b/miosix/_tools/testsuite/mpu_testsuite/test8_2/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test8_2/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test9/Makefile b/miosix/_tools/testsuite/mpu_testsuite/test9/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1523e24bde2cb6937bcc985c1c45062d4987cbdc
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test9/Makefile
@@ -0,0 +1,48 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+DFLAGS    := -MMD -MP
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o test.elf $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  test.elf
+	@arm-miosix-eabi-objdump -Dslx test.elf > test.txt
+	@mx-postlinker test.elf --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i test.elf | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > mpuTest.h
+
+clean:
+	-rm $(OBJ) crt0.o test.elf test.map test.txt mpuTest.h $(OBJ:.o=.d)
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(DFLAGS) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $< -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test9/crt0.s b/miosix/_tools/testsuite/mpu_testsuite/test9/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..7733008e9392ded796006a94a0c1a527a94bfc1a
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test9/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+ 
+.section .text.lseek
+.global lseek
+.type lseek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+*/
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test9/main.c b/miosix/_tools/testsuite/mpu_testsuite/test9/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..c062c0b7a5df820dbf7e601cfcf722be9203afde
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test9/main.c
@@ -0,0 +1,14 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+	//This process sleeps for 5 seconds;
+	usleep(5000000);
+	return 0;
+}
diff --git a/miosix/_tools/testsuite/mpu_testsuite/test9/miosix.ld b/miosix/_tools/testsuite/mpu_testsuite/test9/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/mpu_testsuite/test9/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/build.sh b/miosix/_tools/testsuite/syscall_testsuite/build.sh
new file mode 100644
index 0000000000000000000000000000000000000000..f60111a150f859290883ff94f65fcd0ccd4e5af5
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/build.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+
+
+PREFIX="$1_"
+
+for i in $1_*/; do
+    if [ -d "$i" ]; then
+		echo "Building $i"
+		
+		len=${#i}
+		name=${i:0:len - 1}
+		
+		cd $i &&
+		make clean &&
+		make $2 "NAME=$name" &&
+		cp prog3.h "../$name.h" &&
+		cd ..
+	fi
+done
\ No newline at end of file
diff --git a/miosix/_tools/testsuite/syscall_testsuite/includes.h b/miosix/_tools/testsuite/syscall_testsuite/includes.h
new file mode 100644
index 0000000000000000000000000000000000000000..08007d8fed26c69b6762e06016fb4eecee489a70
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/includes.h
@@ -0,0 +1,15 @@
+#ifndef _APP_SYSCALL_TESTS_
+#define _APP_SYSCALL_TESTS_
+#include "miosix/testsuite/syscall_testsuite/testsuite_syscall.h"
+	#include "miosix/testsuite/syscall_testsuite/testsuite_simple.h"
+	#include "miosix/testsuite/syscall_testsuite/testsuite_sleep.h"
+	#include "miosix/testsuite/syscall_testsuite/testsuite_system.h"
+
+	#ifdef WITH_FILESYSTEM
+		#include "miosix/testsuite/syscall_testsuite/testsuite_file1.h"
+		#include "miosix/testsuite/syscall_testsuite/testsuite_file2.h"
+		#include "miosix/testsuite/syscall_testsuite/testsuite_syscall_mpu_open.h"
+		#include "miosix/testsuite/syscall_testsuite/testsuite_syscall_mpu_read.h"
+		#include "miosix/testsuite/syscall_testsuite/testsuite_syscall_mpu_write.h"
+	#endif
+#endif //_APP_SYSCALL_TESTS_
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1.h
new file mode 100644
index 0000000000000000000000000000000000000000..8cc918ff39a908f43c5cb33f3e9eaa0f97c5ee50
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1.h
@@ -0,0 +1,32 @@
+const unsigned char __attribute__((aligned(8))) testsuite_file1_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
+  0x7e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x24, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x30, 0xf8, 0xf8, 0xb5, 0x16, 0x4f, 0x00, 0x24, 0x09, 0xeb,
+  0x07, 0x03, 0x13, 0xf8, 0x01, 0x2f, 0x01, 0x34, 0x00, 0x2a, 0xfa, 0xd1,
+  0x4f, 0x44, 0x38, 0x46, 0x40, 0xf2, 0x02, 0x41, 0x00, 0xf0, 0x22, 0xf8,
+  0xb0, 0xf1, 0xff, 0x3f, 0x06, 0x46, 0x11, 0xd0, 0x4f, 0xf4, 0x7a, 0x75,
+  0x02, 0xe0, 0x15, 0xf1, 0xff, 0x35, 0x0d, 0xd0, 0x30, 0x46, 0x39, 0x46,
+  0x22, 0x46, 0x00, 0xf0, 0x19, 0xf8, 0xa0, 0x42, 0xf5, 0xd0, 0x30, 0x46,
+  0x00, 0xf0, 0x11, 0xf8, 0x02, 0x20, 0xf8, 0xbd, 0x01, 0x20, 0xfc, 0xe7,
+  0x30, 0x46, 0x00, 0xf0, 0x0a, 0xf8, 0x28, 0x46, 0xf7, 0xe7, 0x00, 0xbf,
+  0x38, 0x00, 0x00, 0x00, 0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf,
+  0x70, 0x47, 0x07, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x03, 0x23, 0x00, 0xdf,
+  0x70, 0x47, 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, 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,
+  0x66, 0x69, 0x6c, 0x65, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0x00, 0x00
+};
+unsigned int testsuite_file1_elf_len = 348;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/Makefile b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..43cfd99a8043902f2cd2b0396930093b0eb18285
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/Makefile
@@ -0,0 +1,46 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+ELF := $(addsuffix .elf, $(NAME))
+OUT_FILE := $(addsuffix .bin, $(shell echo $(NAME) | sed "s/testsuite_//"))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c -DTEST_STRING='"$(OUT_FILE)"' -DTEST_FILE='"$(OUT_FILE)"'
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o $(ELF) $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  $(ELF)
+	@arm-miosix-eabi-objdump -Dslx $(ELF) > test.txt
+	@mx-postlinker $(ELF) --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i $(ELF) | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h
+
+clean:
+	-rm $(OBJ) crt0.o *.elf test.map test.txt
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(CXXFLAGS) $< -o $@
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/crt0.s b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..9959b317dcafd42e8cb82c896b3eef2e0205f7cc
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/crt0.s
@@ -0,0 +1,131 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * seek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+*/
+.section .text.seek
+.global seek
+.type seek, %function
+seek:
+	movs r3, #8
+	svc 0
+	bx lr
+	
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+	
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/main.c b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..050cb85d8333418b320beeeae6fa6c5b9bf4b35d
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/main.c
@@ -0,0 +1,92 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+#define error(x)	(x)
+
+#define SIZE 1024
+
+int mystrlen(const char *s){
+	int result=0;
+	while(*s++) result++;
+	return result;
+}
+
+void print(const char *s){
+	write(1, s, mystrlen(s));
+}
+
+
+char *strrev(char *str, unsigned int len){
+	if(str == 0 || *str == '\0')
+		return str;
+	
+	char tmp = 0, *p1, *p2;
+	for(*p1 = str, *p2 = str + len - 1; p2 > p1; ++p1, --p2){
+		tmp = *p1;
+		*p1 = *p2;
+		*p2 = tmp;
+	}
+
+	return str;
+}
+
+int fast_itoa(int value, char *pBuffer){
+	char *pTmp = pBuffer;
+	unsigned int digitCount = 0;
+
+	if(value == 0){
+		*pTmp = '0';
+		return 1;
+	}
+
+	if(value < 0){
+		value = -value;
+		*pTmp++ = '-';
+		++digitCount;
+	}
+
+	while(value > 0){
+		*pTmp++ = (value % 10) + '0';
+		value /= 10;
+		++digitCount;
+	}
+
+	*pTmp = '\0';
+
+	strrev(pBuffer, digitCount);
+	return digitCount;
+}
+
+int main(){
+	int len = mystrlen(TEST_STRING);
+	
+	int fd = open(TEST_FILE, O_RDWR|O_TRUNC, 0);
+	
+	if(fd == -1)
+		return 1;
+	
+	char buffer[30] = {0};
+	
+	int i = 0;
+	for(i = 0; i < 1000; i++){
+/*		if(i % 10 == 0){
+			fast_itoa(i, buffer);
+			print("\nProcess 1: ");
+			print(buffer);
+		}
+*/					
+		if(write(fd, TEST_STRING, len) != len){
+			close(fd);
+			return 2;
+		}
+	}
+	
+	close(fd);
+
+	return 0;
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/miosix.ld b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/prog3.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/prog3.h
new file mode 100644
index 0000000000000000000000000000000000000000..8cc918ff39a908f43c5cb33f3e9eaa0f97c5ee50
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/prog3.h
@@ -0,0 +1,32 @@
+const unsigned char __attribute__((aligned(8))) testsuite_file1_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
+  0x7e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x24, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x30, 0xf8, 0xf8, 0xb5, 0x16, 0x4f, 0x00, 0x24, 0x09, 0xeb,
+  0x07, 0x03, 0x13, 0xf8, 0x01, 0x2f, 0x01, 0x34, 0x00, 0x2a, 0xfa, 0xd1,
+  0x4f, 0x44, 0x38, 0x46, 0x40, 0xf2, 0x02, 0x41, 0x00, 0xf0, 0x22, 0xf8,
+  0xb0, 0xf1, 0xff, 0x3f, 0x06, 0x46, 0x11, 0xd0, 0x4f, 0xf4, 0x7a, 0x75,
+  0x02, 0xe0, 0x15, 0xf1, 0xff, 0x35, 0x0d, 0xd0, 0x30, 0x46, 0x39, 0x46,
+  0x22, 0x46, 0x00, 0xf0, 0x19, 0xf8, 0xa0, 0x42, 0xf5, 0xd0, 0x30, 0x46,
+  0x00, 0xf0, 0x11, 0xf8, 0x02, 0x20, 0xf8, 0xbd, 0x01, 0x20, 0xfc, 0xe7,
+  0x30, 0x46, 0x00, 0xf0, 0x0a, 0xf8, 0x28, 0x46, 0xf7, 0xe7, 0x00, 0xbf,
+  0x38, 0x00, 0x00, 0x00, 0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf,
+  0x70, 0x47, 0x07, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x03, 0x23, 0x00, 0xdf,
+  0x70, 0x47, 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, 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,
+  0x66, 0x69, 0x6c, 0x65, 0x31, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0x00, 0x00
+};
+unsigned int testsuite_file1_elf_len = 348;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/test.txt b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..29e180990d518bce6cc26c0f293401c88542bcf4
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file1/test.txt
@@ -0,0 +1,151 @@
+
+testsuite_file1.elf:     file format elf32-littlearm
+testsuite_file1.elf
+architecture: arm, flags 0x00000050:
+HAS_SYMS, DYNAMIC
+start address 0x00000099
+
+Program Header:
+    LOAD off    0x00000098 vaddr 0x00000098 paddr 0x00000098 align 2**3
+         filesz 0x0000007e memsz 0x0000007e flags r-x
+    LOAD off    0x00000118 vaddr 0x10000000 paddr 0x10000000 align 2**3
+         filesz 0x00000044 memsz 0x00000044 flags rw-
+ DYNAMIC off    0x00000124 vaddr 0x1000000c paddr 0x1000000c align 2**2
+         filesz 0x00000028 memsz 0x00000028 flags rw-
+
+Dynamic Section:
+  DEBUG                0x00000000
+private flags = 5000002: [Version5 EABI] [has entry point]
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .text         0000007e  00000098  00000098  00000098  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+  1 .got          0000000c  10000000  10000000  00000118  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  2 .dynamic      00000028  1000000c  1000000c  00000124  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  3 .rodata       0000000c  10000038  10000038  00000150  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, DATA
+SYMBOL TABLE:
+00000098 l    d  .text	00000000 .text
+10000000 l    d  .got	00000000 .got
+1000000c l    d  .dynamic	00000000 .dynamic
+10000038 l    d  .rodata	00000000 .rodata
+00000000 l    df *ABS*	00000000 main.c
+1000000c l     O *ABS*	00000000 _DYNAMIC
+10000000 l     O *ABS*	00000000 _GLOBAL_OFFSET_TABLE_
+00000110 g     F .text	00000000 write
+00000098 g     F .text	00000000 _start
+000000a0 g     F .text	00000060 main
+00000100 g     F .text	00000000 _exit
+00000104 g     F .text	00000000 open
+0000010a g     F .text	00000000 close
+
+
+Contents of section .text:
+ 0098 00f002f8 00f030f8 f8b5164f 002409eb  ......0....O.$..
+ 00a8 070313f8 012f0134 002afad1 4f443846  ...../.4.*..OD8F
+ 00b8 40f20241 00f022f8 b0f1ff3f 064611d0  @..A.."....?.F..
+ 00c8 4ff47a75 02e015f1 ff350dd0 30463946  O.zu.....5..0F9F
+ 00d8 224600f0 19f8a042 f5d03046 00f011f8  "F.....B..0F....
+ 00e8 0220f8bd 0120fce7 304600f0 0af82846  . ... ..0F....(F
+ 00f8 f7e700bf 38000000 022300df 062300df  ....8....#...#..
+ 0108 70470723 00df7047 032300df 7047      pG.#..pG.#..pG  
+Contents of section .got:
+ 10000000 0c000010 00000000 00000000           ............    
+Contents of section .dynamic:
+ 1000000c 15000000 00000000 00000000 00000000  ................
+ 1000001c 00000000 00000000 00000000 00000000  ................
+ 1000002c 00000000 00000000                    ........        
+Contents of section .rodata:
+ 10000038 66696c65 312e6269 6e000000           file1.bin...    
+
+Disassembly of section .text:
+
+00000098 <_start>:
+_start():
+  98:	f000 f802 	bl	a0 <main>
+  9c:	f000 f830 	bl	100 <_exit>
+
+000000a0 <main>:
+main():
+  a0:	b5f8      	push	{r3, r4, r5, r6, r7, lr}
+  a2:	4f16      	ldr	r7, [pc, #88]	; (fc <main+0x5c>)
+  a4:	2400      	movs	r4, #0
+  a6:	eb09 0307 	add.w	r3, r9, r7
+  aa:	f813 2f01 	ldrb.w	r2, [r3, #1]!
+  ae:	3401      	adds	r4, #1
+  b0:	2a00      	cmp	r2, #0
+  b2:	d1fa      	bne.n	aa <main+0xa>
+  b4:	444f      	add	r7, r9
+  b6:	4638      	mov	r0, r7
+  b8:	f240 4102 	movw	r1, #1026	; 0x402
+  bc:	f000 f822 	bl	104 <open>
+  c0:	f1b0 3fff 	cmp.w	r0, #4294967295	; 0xffffffff
+  c4:	4606      	mov	r6, r0
+  c6:	d011      	beq.n	ec <main+0x4c>
+  c8:	f44f 757a 	mov.w	r5, #1000	; 0x3e8
+  cc:	e002      	b.n	d4 <main+0x34>
+  ce:	f115 35ff 	adds.w	r5, r5, #4294967295	; 0xffffffff
+  d2:	d00d      	beq.n	f0 <main+0x50>
+  d4:	4630      	mov	r0, r6
+  d6:	4639      	mov	r1, r7
+  d8:	4622      	mov	r2, r4
+  da:	f000 f819 	bl	110 <write>
+  de:	42a0      	cmp	r0, r4
+  e0:	d0f5      	beq.n	ce <main+0x2e>
+  e2:	4630      	mov	r0, r6
+  e4:	f000 f811 	bl	10a <close>
+  e8:	2002      	movs	r0, #2
+  ea:	bdf8      	pop	{r3, r4, r5, r6, r7, pc}
+  ec:	2001      	movs	r0, #1
+  ee:	e7fc      	b.n	ea <main+0x4a>
+  f0:	4630      	mov	r0, r6
+  f2:	f000 f80a 	bl	10a <close>
+  f6:	4628      	mov	r0, r5
+  f8:	e7f7      	b.n	ea <main+0x4a>
+  fa:	bf00      	nop
+  fc:	00000038 	andeq	r0, r0, r8, lsr r0
+
+00000100 <_exit>:
+_exit():
+ 100:	2302      	movs	r3, #2
+ 102:	df00      	svc	0
+
+00000104 <open>:
+open():
+ 104:	2306      	movs	r3, #6
+ 106:	df00      	svc	0
+ 108:	4770      	bx	lr
+
+0000010a <close>:
+close():
+ 10a:	2307      	movs	r3, #7
+ 10c:	df00      	svc	0
+ 10e:	4770      	bx	lr
+
+00000110 <write>:
+write():
+ 110:	2303      	movs	r3, #3
+ 112:	df00      	svc	0
+ 114:	4770      	bx	lr
+
+Disassembly of section .got:
+
+10000000 <.got>:
+10000000:	1000000c 	andne	r0, r0, ip
+	...
+
+Disassembly of section .dynamic:
+
+1000000c <.dynamic>:
+1000000c:	00000015 	andeq	r0, r0, r5, lsl r0
+	...
+
+Disassembly of section .rodata:
+
+10000038 <.rodata>:
+10000038:	656c6966 	strbvs	r6, [ip, #-2406]!	; 0x966
+1000003c:	69622e31 	stmdbvs	r2!, {r0, r4, r5, r9, sl, fp, sp}^
+10000040:	0000006e 	andeq	r0, r0, lr, rrx
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2.h
new file mode 100644
index 0000000000000000000000000000000000000000..ddab5d4cace1fc0bdfbee7550a5f6347b10f9c42
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2.h
@@ -0,0 +1,32 @@
+const unsigned char __attribute__((aligned(8))) testsuite_file2_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
+  0x7e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x24, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x30, 0xf8, 0xf8, 0xb5, 0x16, 0x4f, 0x00, 0x24, 0x09, 0xeb,
+  0x07, 0x03, 0x13, 0xf8, 0x01, 0x2f, 0x01, 0x34, 0x00, 0x2a, 0xfa, 0xd1,
+  0x4f, 0x44, 0x38, 0x46, 0x40, 0xf2, 0x02, 0x41, 0x00, 0xf0, 0x22, 0xf8,
+  0xb0, 0xf1, 0xff, 0x3f, 0x06, 0x46, 0x11, 0xd0, 0x4f, 0xf4, 0x7a, 0x75,
+  0x02, 0xe0, 0x15, 0xf1, 0xff, 0x35, 0x0d, 0xd0, 0x30, 0x46, 0x39, 0x46,
+  0x22, 0x46, 0x00, 0xf0, 0x19, 0xf8, 0xa0, 0x42, 0xf5, 0xd0, 0x30, 0x46,
+  0x00, 0xf0, 0x11, 0xf8, 0x02, 0x20, 0xf8, 0xbd, 0x01, 0x20, 0xfc, 0xe7,
+  0x30, 0x46, 0x00, 0xf0, 0x0a, 0xf8, 0x28, 0x46, 0xf7, 0xe7, 0x00, 0xbf,
+  0x38, 0x00, 0x00, 0x00, 0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf,
+  0x70, 0x47, 0x07, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x03, 0x23, 0x00, 0xdf,
+  0x70, 0x47, 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, 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,
+  0x66, 0x69, 0x6c, 0x65, 0x32, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0x00, 0x00
+};
+unsigned int testsuite_file2_elf_len = 348;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/Makefile b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..43cfd99a8043902f2cd2b0396930093b0eb18285
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/Makefile
@@ -0,0 +1,46 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+ELF := $(addsuffix .elf, $(NAME))
+OUT_FILE := $(addsuffix .bin, $(shell echo $(NAME) | sed "s/testsuite_//"))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c -DTEST_STRING='"$(OUT_FILE)"' -DTEST_FILE='"$(OUT_FILE)"'
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o $(ELF) $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  $(ELF)
+	@arm-miosix-eabi-objdump -Dslx $(ELF) > test.txt
+	@mx-postlinker $(ELF) --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i $(ELF) | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h
+
+clean:
+	-rm $(OBJ) crt0.o *.elf test.map test.txt
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(CXXFLAGS) $< -o $@
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/crt0.s b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..9959b317dcafd42e8cb82c896b3eef2e0205f7cc
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/crt0.s
@@ -0,0 +1,131 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * seek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+*/
+.section .text.seek
+.global seek
+.type seek, %function
+seek:
+	movs r3, #8
+	svc 0
+	bx lr
+	
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+	
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/main.c b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..93f4b2d17e92d049b322192644047c8cae687d95
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/main.c
@@ -0,0 +1,92 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+#define error(x)	(x)
+
+#define SIZE 1024
+
+int mystrlen(const char *s){
+	int result=0;
+	while(*s++) result++;
+	return result;
+}
+
+void print(const char *s){
+	write(1, s, mystrlen(s));
+}
+
+
+char *strrev(char *str, unsigned int len){
+	if(str == 0 || *str == '\0')
+		return str;
+	
+	char tmp = 0, *p1, *p2;
+	for(*p1 = str, *p2 = str + len - 1; p2 > p1; ++p1, --p2){
+		tmp = *p1;
+		*p1 = *p2;
+		*p2 = tmp;
+	}
+
+	return str;
+}
+
+int fast_itoa(int value, char *pBuffer){
+	char *pTmp = pBuffer;
+	unsigned int digitCount = 0;
+
+	if(value == 0){
+		*pTmp = '0';
+		return 1;
+	}
+
+	if(value < 0){
+		value = -value;
+		*pTmp++ = '-';
+		++digitCount;
+	}
+
+	while(value > 0){
+		*pTmp++ = (value % 10) + '0';
+		value /= 10;
+		++digitCount;
+	}
+
+	*pTmp = '\0';
+
+	strrev(pBuffer, digitCount);
+	return digitCount;
+}
+
+int main(){
+	int len = mystrlen(TEST_STRING);
+	
+	int fd = open(TEST_FILE, O_RDWR|O_TRUNC, 0);
+	
+	if(fd == -1)
+		return 1;
+	
+	char buffer[30] = {0};
+	
+	int i = 0;
+	for(i = 0; i < 1000; i++){
+/*		if(i % 10 == 0){
+			fast_itoa(i, buffer);
+			print("\nProcess 2: ");
+			print(buffer);
+		}
+	*/				
+		if(write(fd, TEST_STRING, len) != len){
+			close(fd);
+			return 2;
+		}
+	}
+	
+	close(fd);
+
+	return 0;
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/miosix.ld b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/prog3.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/prog3.h
new file mode 100644
index 0000000000000000000000000000000000000000..ddab5d4cace1fc0bdfbee7550a5f6347b10f9c42
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/prog3.h
@@ -0,0 +1,32 @@
+const unsigned char __attribute__((aligned(8))) testsuite_file2_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00,
+  0x7e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x24, 0x01, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x30, 0xf8, 0xf8, 0xb5, 0x16, 0x4f, 0x00, 0x24, 0x09, 0xeb,
+  0x07, 0x03, 0x13, 0xf8, 0x01, 0x2f, 0x01, 0x34, 0x00, 0x2a, 0xfa, 0xd1,
+  0x4f, 0x44, 0x38, 0x46, 0x40, 0xf2, 0x02, 0x41, 0x00, 0xf0, 0x22, 0xf8,
+  0xb0, 0xf1, 0xff, 0x3f, 0x06, 0x46, 0x11, 0xd0, 0x4f, 0xf4, 0x7a, 0x75,
+  0x02, 0xe0, 0x15, 0xf1, 0xff, 0x35, 0x0d, 0xd0, 0x30, 0x46, 0x39, 0x46,
+  0x22, 0x46, 0x00, 0xf0, 0x19, 0xf8, 0xa0, 0x42, 0xf5, 0xd0, 0x30, 0x46,
+  0x00, 0xf0, 0x11, 0xf8, 0x02, 0x20, 0xf8, 0xbd, 0x01, 0x20, 0xfc, 0xe7,
+  0x30, 0x46, 0x00, 0xf0, 0x0a, 0xf8, 0x28, 0x46, 0xf7, 0xe7, 0x00, 0xbf,
+  0x38, 0x00, 0x00, 0x00, 0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf,
+  0x70, 0x47, 0x07, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x03, 0x23, 0x00, 0xdf,
+  0x70, 0x47, 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, 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,
+  0x66, 0x69, 0x6c, 0x65, 0x32, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0x00, 0x00
+};
+unsigned int testsuite_file2_elf_len = 348;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/test.txt b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..f7d071064a572b83ac6ab49834ffa054d70e7588
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_file2/test.txt
@@ -0,0 +1,151 @@
+
+testsuite_file2.elf:     file format elf32-littlearm
+testsuite_file2.elf
+architecture: arm, flags 0x00000050:
+HAS_SYMS, DYNAMIC
+start address 0x00000099
+
+Program Header:
+    LOAD off    0x00000098 vaddr 0x00000098 paddr 0x00000098 align 2**3
+         filesz 0x0000007e memsz 0x0000007e flags r-x
+    LOAD off    0x00000118 vaddr 0x10000000 paddr 0x10000000 align 2**3
+         filesz 0x00000044 memsz 0x00000044 flags rw-
+ DYNAMIC off    0x00000124 vaddr 0x1000000c paddr 0x1000000c align 2**2
+         filesz 0x00000028 memsz 0x00000028 flags rw-
+
+Dynamic Section:
+  DEBUG                0x00000000
+private flags = 5000002: [Version5 EABI] [has entry point]
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .text         0000007e  00000098  00000098  00000098  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+  1 .got          0000000c  10000000  10000000  00000118  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  2 .dynamic      00000028  1000000c  1000000c  00000124  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  3 .rodata       0000000c  10000038  10000038  00000150  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, DATA
+SYMBOL TABLE:
+00000098 l    d  .text	00000000 .text
+10000000 l    d  .got	00000000 .got
+1000000c l    d  .dynamic	00000000 .dynamic
+10000038 l    d  .rodata	00000000 .rodata
+00000000 l    df *ABS*	00000000 main.c
+1000000c l     O *ABS*	00000000 _DYNAMIC
+10000000 l     O *ABS*	00000000 _GLOBAL_OFFSET_TABLE_
+00000110 g     F .text	00000000 write
+00000098 g     F .text	00000000 _start
+000000a0 g     F .text	00000060 main
+00000100 g     F .text	00000000 _exit
+00000104 g     F .text	00000000 open
+0000010a g     F .text	00000000 close
+
+
+Contents of section .text:
+ 0098 00f002f8 00f030f8 f8b5164f 002409eb  ......0....O.$..
+ 00a8 070313f8 012f0134 002afad1 4f443846  ...../.4.*..OD8F
+ 00b8 40f20241 00f022f8 b0f1ff3f 064611d0  @..A.."....?.F..
+ 00c8 4ff47a75 02e015f1 ff350dd0 30463946  O.zu.....5..0F9F
+ 00d8 224600f0 19f8a042 f5d03046 00f011f8  "F.....B..0F....
+ 00e8 0220f8bd 0120fce7 304600f0 0af82846  . ... ..0F....(F
+ 00f8 f7e700bf 38000000 022300df 062300df  ....8....#...#..
+ 0108 70470723 00df7047 032300df 7047      pG.#..pG.#..pG  
+Contents of section .got:
+ 10000000 0c000010 00000000 00000000           ............    
+Contents of section .dynamic:
+ 1000000c 15000000 00000000 00000000 00000000  ................
+ 1000001c 00000000 00000000 00000000 00000000  ................
+ 1000002c 00000000 00000000                    ........        
+Contents of section .rodata:
+ 10000038 66696c65 322e6269 6e000000           file2.bin...    
+
+Disassembly of section .text:
+
+00000098 <_start>:
+_start():
+  98:	f000 f802 	bl	a0 <main>
+  9c:	f000 f830 	bl	100 <_exit>
+
+000000a0 <main>:
+main():
+  a0:	b5f8      	push	{r3, r4, r5, r6, r7, lr}
+  a2:	4f16      	ldr	r7, [pc, #88]	; (fc <main+0x5c>)
+  a4:	2400      	movs	r4, #0
+  a6:	eb09 0307 	add.w	r3, r9, r7
+  aa:	f813 2f01 	ldrb.w	r2, [r3, #1]!
+  ae:	3401      	adds	r4, #1
+  b0:	2a00      	cmp	r2, #0
+  b2:	d1fa      	bne.n	aa <main+0xa>
+  b4:	444f      	add	r7, r9
+  b6:	4638      	mov	r0, r7
+  b8:	f240 4102 	movw	r1, #1026	; 0x402
+  bc:	f000 f822 	bl	104 <open>
+  c0:	f1b0 3fff 	cmp.w	r0, #4294967295	; 0xffffffff
+  c4:	4606      	mov	r6, r0
+  c6:	d011      	beq.n	ec <main+0x4c>
+  c8:	f44f 757a 	mov.w	r5, #1000	; 0x3e8
+  cc:	e002      	b.n	d4 <main+0x34>
+  ce:	f115 35ff 	adds.w	r5, r5, #4294967295	; 0xffffffff
+  d2:	d00d      	beq.n	f0 <main+0x50>
+  d4:	4630      	mov	r0, r6
+  d6:	4639      	mov	r1, r7
+  d8:	4622      	mov	r2, r4
+  da:	f000 f819 	bl	110 <write>
+  de:	42a0      	cmp	r0, r4
+  e0:	d0f5      	beq.n	ce <main+0x2e>
+  e2:	4630      	mov	r0, r6
+  e4:	f000 f811 	bl	10a <close>
+  e8:	2002      	movs	r0, #2
+  ea:	bdf8      	pop	{r3, r4, r5, r6, r7, pc}
+  ec:	2001      	movs	r0, #1
+  ee:	e7fc      	b.n	ea <main+0x4a>
+  f0:	4630      	mov	r0, r6
+  f2:	f000 f80a 	bl	10a <close>
+  f6:	4628      	mov	r0, r5
+  f8:	e7f7      	b.n	ea <main+0x4a>
+  fa:	bf00      	nop
+  fc:	00000038 	andeq	r0, r0, r8, lsr r0
+
+00000100 <_exit>:
+_exit():
+ 100:	2302      	movs	r3, #2
+ 102:	df00      	svc	0
+
+00000104 <open>:
+open():
+ 104:	2306      	movs	r3, #6
+ 106:	df00      	svc	0
+ 108:	4770      	bx	lr
+
+0000010a <close>:
+close():
+ 10a:	2307      	movs	r3, #7
+ 10c:	df00      	svc	0
+ 10e:	4770      	bx	lr
+
+00000110 <write>:
+write():
+ 110:	2303      	movs	r3, #3
+ 112:	df00      	svc	0
+ 114:	4770      	bx	lr
+
+Disassembly of section .got:
+
+10000000 <.got>:
+10000000:	1000000c 	andne	r0, r0, ip
+	...
+
+Disassembly of section .dynamic:
+
+1000000c <.dynamic>:
+1000000c:	00000015 	andeq	r0, r0, r5, lsl r0
+	...
+
+Disassembly of section .rodata:
+
+10000038 <.rodata>:
+10000038:	656c6966 	strbvs	r6, [ip, #-2406]!	; 0x966
+1000003c:	69622e32 	stmdbvs	r2!, {r1, r4, r5, r9, sl, fp, sp}^
+10000040:	0000006e 	andeq	r0, r0, lr, rrx
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple.h
new file mode 100644
index 0000000000000000000000000000000000000000..fd4cd50e8f54a68798894d655bb04cefa7a56827
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple.h
@@ -0,0 +1,22 @@
+const unsigned char __attribute__((aligned(8))) testsuite_simple_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xb4, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x02, 0xf8, 0x2a, 0x20, 0x70, 0x47, 0x02, 0x23, 0x00, 0xdf,
+  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, 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
+};
+unsigned int testsuite_simple_elf_len = 220;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/Makefile b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..4f84bfef8faef0da502b49682e72369cb498ee1a
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/Makefile
@@ -0,0 +1,45 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+ELF := $(addsuffix .elf, $(NAME))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c -DRETURN_VALUE=$(RET)
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o $(ELF) $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  $(ELF)
+	@arm-miosix-eabi-objdump -Dslx $(ELF) > test.txt
+	@mx-postlinker $(ELF) --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i $(ELF) | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h
+
+clean:
+	-rm $(OBJ) crt0.o *.elf test.map test.txt
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(CXXFLAGS) $< -o $@
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/crt0.s b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..8dbb153d806028cd739d686a05eac59d6357eb74
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+*/ 
+.section .text.seek
+.global seek
+.type seek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/main.c b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..00ea56a6cfa7fab92fcea8a9440dc31088dc19aa
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/main.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(){
+	return RETURN_VALUE;
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/miosix.ld b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/prog3.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/prog3.h
new file mode 100644
index 0000000000000000000000000000000000000000..fd4cd50e8f54a68798894d655bb04cefa7a56827
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/prog3.h
@@ -0,0 +1,22 @@
+const unsigned char __attribute__((aligned(8))) testsuite_simple_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xb4, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x02, 0xf8, 0x2a, 0x20, 0x70, 0x47, 0x02, 0x23, 0x00, 0xdf,
+  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, 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
+};
+unsigned int testsuite_simple_elf_len = 220;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/test.txt b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8e8264dfccb9d5bcedc3af5fd8bebe179a7a3eda
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_simple/test.txt
@@ -0,0 +1,77 @@
+
+testsuite_simple.elf:     file format elf32-littlearm
+testsuite_simple.elf
+architecture: arm, flags 0x00000050:
+HAS_SYMS, DYNAMIC
+start address 0x00000099
+
+Program Header:
+    LOAD off    0x00000098 vaddr 0x00000098 paddr 0x00000098 align 2**3
+         filesz 0x00000010 memsz 0x00000010 flags r-x
+    LOAD off    0x000000a8 vaddr 0x10000000 paddr 0x10000000 align 2**2
+         filesz 0x00000034 memsz 0x00000034 flags rw-
+ DYNAMIC off    0x000000b4 vaddr 0x1000000c paddr 0x1000000c align 2**2
+         filesz 0x00000028 memsz 0x00000028 flags rw-
+
+Dynamic Section:
+  DEBUG                0x00000000
+private flags = 5000002: [Version5 EABI] [has entry point]
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .text         00000010  00000098  00000098  00000098  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+  1 .got          0000000c  10000000  10000000  000000a8  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  2 .dynamic      00000028  1000000c  1000000c  000000b4  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+SYMBOL TABLE:
+00000098 l    d  .text	00000000 .text
+10000000 l    d  .got	00000000 .got
+1000000c l    d  .dynamic	00000000 .dynamic
+00000000 l    df *ABS*	00000000 main.c
+1000000c l     O *ABS*	00000000 _DYNAMIC
+10000000 l     O *ABS*	00000000 _GLOBAL_OFFSET_TABLE_
+00000098 g     F .text	00000000 _start
+000000a0 g     F .text	00000004 main
+00000000       F *UND*	00000000 seek
+000000a4 g     F .text	00000000 _exit
+
+
+Contents of section .text:
+ 0098 00f002f8 00f002f8 2a207047 022300df  ........* pG.#..
+Contents of section .got:
+ 10000000 0c000010 00000000 00000000           ............    
+Contents of section .dynamic:
+ 1000000c 15000000 00000000 00000000 00000000  ................
+ 1000001c 00000000 00000000 00000000 00000000  ................
+ 1000002c 00000000 00000000                    ........        
+
+Disassembly of section .text:
+
+00000098 <_start>:
+_start():
+  98:	f000 f802 	bl	a0 <main>
+  9c:	f000 f802 	bl	a4 <_exit>
+
+000000a0 <main>:
+main():
+  a0:	202a      	movs	r0, #42	; 0x2a
+  a2:	4770      	bx	lr
+
+000000a4 <_exit>:
+_exit():
+  a4:	2302      	movs	r3, #2
+  a6:	df00      	svc	0
+
+Disassembly of section .got:
+
+10000000 <.got>:
+10000000:	1000000c 	andne	r0, r0, ip
+	...
+
+Disassembly of section .dynamic:
+
+1000000c <.dynamic>:
+1000000c:	00000015 	andeq	r0, r0, r5, lsl r0
+	...
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep.h
new file mode 100644
index 0000000000000000000000000000000000000000..bfe5d3e1198241e1f346f8b3bd858e3a792b007f
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep.h
@@ -0,0 +1,23 @@
+const unsigned char __attribute__((aligned(8))) testsuite_sleep_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+  0x22, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xc8, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x08, 0xf8, 0x44, 0xf6, 0x40, 0x30, 0x08, 0xb5, 0xc0, 0xf2,
+  0x4c, 0x00, 0x00, 0xf0, 0x03, 0xf8, 0x08, 0xbd, 0x02, 0x23, 0x00, 0xdf,
+  0x05, 0x23, 0x00, 0xdf, 0x70, 0x47, 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, 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
+};
+unsigned int testsuite_sleep_elf_len = 240;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/Makefile b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..34f92e723fa43f571d53cbaaddcc9329cd32cb2b
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/Makefile
@@ -0,0 +1,45 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+ELF := $(addsuffix .elf, $(NAME))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o $(ELF) $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  $(ELF)
+	@arm-miosix-eabi-objdump -Dslx $(ELF) > test.txt
+	@mx-postlinker $(ELF) --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i $(ELF) | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h
+
+clean:
+	-rm $(OBJ) crt0.o *.elf test.map test.txt
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(CXXFLAGS) $< -o $@
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/crt0.s b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..9959b317dcafd42e8cb82c896b3eef2e0205f7cc
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/crt0.s
@@ -0,0 +1,131 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * seek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+*/
+.section .text.seek
+.global seek
+.type seek, %function
+seek:
+	movs r3, #8
+	svc 0
+	bx lr
+	
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+	
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/main.c b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..5a9879272656419fc23edc5598860250a348a9c1
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/main.c
@@ -0,0 +1,11 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main(){
+	usleep(5000000);
+}
\ No newline at end of file
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/miosix.ld b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/prog3.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/prog3.h
new file mode 100644
index 0000000000000000000000000000000000000000..bfe5d3e1198241e1f346f8b3bd858e3a792b007f
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/prog3.h
@@ -0,0 +1,23 @@
+const unsigned char __attribute__((aligned(8))) testsuite_sleep_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+  0x22, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xc8, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x08, 0xf8, 0x44, 0xf6, 0x40, 0x30, 0x08, 0xb5, 0xc0, 0xf2,
+  0x4c, 0x00, 0x00, 0xf0, 0x03, 0xf8, 0x08, 0xbd, 0x02, 0x23, 0x00, 0xdf,
+  0x05, 0x23, 0x00, 0xdf, 0x70, 0x47, 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, 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
+};
+unsigned int testsuite_sleep_elf_len = 240;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/test.txt b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..c860216c5de5f69f8ca14ca07ced9e20b29fb21b
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_sleep/test.txt
@@ -0,0 +1,88 @@
+
+testsuite_sleep.elf:     file format elf32-littlearm
+testsuite_sleep.elf
+architecture: arm, flags 0x00000050:
+HAS_SYMS, DYNAMIC
+start address 0x00000099
+
+Program Header:
+    LOAD off    0x00000098 vaddr 0x00000098 paddr 0x00000098 align 2**3
+         filesz 0x00000022 memsz 0x00000022 flags r-x
+    LOAD off    0x000000bc vaddr 0x10000000 paddr 0x10000000 align 2**2
+         filesz 0x00000034 memsz 0x00000034 flags rw-
+ DYNAMIC off    0x000000c8 vaddr 0x1000000c paddr 0x1000000c align 2**2
+         filesz 0x00000028 memsz 0x00000028 flags rw-
+
+Dynamic Section:
+  DEBUG                0x00000000
+private flags = 5000002: [Version5 EABI] [has entry point]
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .text         00000022  00000098  00000098  00000098  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+  1 .got          0000000c  10000000  10000000  000000bc  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  2 .dynamic      00000028  1000000c  1000000c  000000c8  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+SYMBOL TABLE:
+00000098 l    d  .text	00000000 .text
+10000000 l    d  .got	00000000 .got
+1000000c l    d  .dynamic	00000000 .dynamic
+00000000 l    df *ABS*	00000000 main.c
+1000000c l     O *ABS*	00000000 _DYNAMIC
+10000000 l     O *ABS*	00000000 _GLOBAL_OFFSET_TABLE_
+000000b4 g     F .text	00000000 usleep
+00000098 g     F .text	00000000 _start
+000000a0 g     F .text	00000010 main
+000000b0 g     F .text	00000000 _exit
+
+
+Contents of section .text:
+ 0098 00f002f8 00f008f8 44f64030 08b5c0f2  ........D.@0....
+ 00a8 4c0000f0 03f808bd 022300df 052300df  L........#...#..
+ 00b8 7047                                 pG              
+Contents of section .got:
+ 10000000 0c000010 00000000 00000000           ............    
+Contents of section .dynamic:
+ 1000000c 15000000 00000000 00000000 00000000  ................
+ 1000001c 00000000 00000000 00000000 00000000  ................
+ 1000002c 00000000 00000000                    ........        
+
+Disassembly of section .text:
+
+00000098 <_start>:
+_start():
+  98:	f000 f802 	bl	a0 <main>
+  9c:	f000 f808 	bl	b0 <_exit>
+
+000000a0 <main>:
+main():
+  a0:	f644 3040 	movw	r0, #19264	; 0x4b40
+  a4:	b508      	push	{r3, lr}
+  a6:	f2c0 004c 	movt	r0, #76	; 0x4c
+  aa:	f000 f803 	bl	b4 <usleep>
+  ae:	bd08      	pop	{r3, pc}
+
+000000b0 <_exit>:
+_exit():
+  b0:	2302      	movs	r3, #2
+  b2:	df00      	svc	0
+
+000000b4 <usleep>:
+usleep():
+  b4:	2305      	movs	r3, #5
+  b6:	df00      	svc	0
+  b8:	4770      	bx	lr
+
+Disassembly of section .got:
+
+10000000 <.got>:
+10000000:	1000000c 	andne	r0, r0, ip
+	...
+
+Disassembly of section .dynamic:
+
+1000000c <.dynamic>:
+1000000c:	00000015 	andeq	r0, r0, r5, lsl r0
+	...
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall.h
new file mode 100644
index 0000000000000000000000000000000000000000..9da3e20b11c45059b60ad04de99553c35c631c7b
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall.h
@@ -0,0 +1,75 @@
+const unsigned char __attribute__((aligned(8))) testsuite_syscall_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0xbe, 0x01, 0x00, 0x00,
+  0xbe, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x04, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x64, 0x02, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x10, 0xf8,
+  0x00, 0xf0, 0xca, 0xf8, 0x08, 0xb5, 0x02, 0x78, 0x01, 0x46, 0x22, 0xb1,
+  0x00, 0x22, 0x01, 0x32, 0x8b, 0x5c, 0x00, 0x2b, 0xfb, 0xd1, 0x01, 0x20,
+  0x00, 0xf0, 0xc9, 0xf8, 0x08, 0xbd, 0x00, 0xbf, 0x2d, 0xe9, 0xf0, 0x45,
+  0xad, 0xf5, 0x00, 0x6d, 0x81, 0xb0, 0x00, 0x24, 0x0d, 0xf5, 0x80, 0x65,
+  0x2c, 0x55, 0x01, 0x34, 0xb4, 0xf5, 0x80, 0x6f, 0xfa, 0xd1, 0x4e, 0x4f,
+  0x02, 0x21, 0x09, 0xeb, 0x07, 0x06, 0x00, 0x22, 0x30, 0x46, 0x00, 0xf0,
+  0xa9, 0xf8, 0xb0, 0xf1, 0xff, 0x3f, 0x05, 0xd0, 0x01, 0x20, 0x01, 0xb0,
+  0x0d, 0xf5, 0x00, 0x6d, 0xbd, 0xe8, 0xf0, 0x85, 0x00, 0xf0, 0xa1, 0xf8,
+  0x45, 0x48, 0x48, 0x44, 0xff, 0xf7, 0xce, 0xff, 0x30, 0x46, 0x00, 0x22,
+  0x40, 0xf2, 0x02, 0x41, 0x00, 0xf0, 0x94, 0xf8, 0xb0, 0xf1, 0xff, 0x3f,
+  0x06, 0x46, 0x11, 0xd0, 0x02, 0x28, 0x01, 0xd8, 0x03, 0x20, 0xe6, 0xe7,
+  0x3d, 0x48, 0x48, 0x44, 0xff, 0xf7, 0xbc, 0xff, 0x30, 0x46, 0x29, 0x46,
+  0x22, 0x46, 0x00, 0xf0, 0x8c, 0xf8, 0xb0, 0xf5, 0x80, 0x6f, 0x03, 0xd0,
+  0x04, 0x20, 0xd8, 0xe7, 0x02, 0x20, 0xd6, 0xe7, 0x36, 0x48, 0xe8, 0x46,
+  0x48, 0x44, 0xff, 0xf7, 0xab, 0xff, 0x00, 0x21, 0x0a, 0x46, 0x30, 0x46,
+  0x00, 0xf0, 0x78, 0xf8, 0x30, 0x46, 0x69, 0x46, 0x22, 0x46, 0x00, 0xf0,
+  0x79, 0xf8, 0xb0, 0xf5, 0x80, 0x6f, 0x01, 0xd0, 0x05, 0x20, 0xc2, 0xe7,
+  0x4f, 0xf0, 0x00, 0x0a, 0x02, 0xe0, 0xba, 0xf5, 0x80, 0x6f, 0x09, 0xd0,
+  0x15, 0xf8, 0x0a, 0x20, 0x18, 0xf8, 0x0a, 0x30, 0x0a, 0xf1, 0x01, 0x0a,
+  0x9a, 0x42, 0xf4, 0xd0, 0x06, 0x20, 0xb2, 0xe7, 0x25, 0x48, 0x48, 0x44,
+  0xff, 0xf7, 0x88, 0xff, 0x30, 0x46, 0x00, 0xf0, 0x54, 0xf8, 0x06, 0x46,
+  0x08, 0xb1, 0x07, 0x20, 0xa7, 0xe7, 0x21, 0x48, 0x48, 0x44, 0xff, 0xf7,
+  0x7d, 0xff, 0x02, 0x21, 0x09, 0xeb, 0x07, 0x00, 0x00, 0xf0, 0x44, 0xf8,
+  0x01, 0x28, 0x04, 0x46, 0x0d, 0xdd, 0x1c, 0x48, 0x48, 0x44, 0xff, 0xf7,
+  0x71, 0xff, 0x20, 0x46, 0x69, 0x46, 0x52, 0x46, 0x00, 0xf0, 0x44, 0xf8,
+  0xb0, 0xf5, 0x80, 0x6f, 0x03, 0xd0, 0x09, 0x20, 0x8d, 0xe7, 0x08, 0x20,
+  0x8b, 0xe7, 0xaa, 0x5d, 0x18, 0xf8, 0x06, 0x30, 0x01, 0x36, 0x9a, 0x42,
+  0x0d, 0xd1, 0xb6, 0xf5, 0x80, 0x6f, 0xf6, 0xd1, 0x10, 0x48, 0x48, 0x44,
+  0xff, 0xf7, 0x58, 0xff, 0x20, 0x46, 0x00, 0xf0, 0x24, 0xf8, 0x04, 0x46,
+  0x18, 0xb1, 0x0b, 0x20, 0x77, 0xe7, 0x0a, 0x20, 0x75, 0xe7, 0x0b, 0x48,
+  0x48, 0x44, 0xff, 0xf7, 0x4b, 0xff, 0x20, 0x46, 0x6f, 0xe7, 0x00, 0xbf,
+  0x38, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
+  0x7c, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+  0xb0, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00,
+  0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x07, 0x23,
+  0x00, 0xdf, 0x70, 0x47, 0x08, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x03, 0x23,
+  0x00, 0xdf, 0x70, 0x47, 0x04, 0x23, 0x00, 0xdf, 0x70, 0x47, 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, 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, 0x66, 0x6f, 0x6f, 0x2e,
+  0x62, 0x69, 0x6e, 0x00, 0x27, 0x4f, 0x70, 0x65, 0x6e, 0x27, 0x20, 0x6f,
+  0x66, 0x20, 0x6e, 0x6f, 0x6e, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69,
+  0x6e, 0x67, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x20, 0x50, 0x61, 0x73,
+  0x73, 0x65, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x70, 0x65, 0x6e,
+  0x20, 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x20, 0x50, 0x61, 0x73, 0x73, 0x65,
+  0x64, 0x0a, 0x00, 0x00, 0x57, 0x72, 0x69, 0x74, 0x65, 0x20, 0x66, 0x69,
+  0x6c, 0x65, 0x3a, 0x20, 0x50, 0x61, 0x73, 0x73, 0x65, 0x64, 0x0a, 0x00,
+  0x52, 0x65, 0x61, 0x64, 0x3a, 0x20, 0x50, 0x61, 0x73, 0x73, 0x65, 0x64,
+  0x0a, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x3a, 0x20, 0x50,
+  0x61, 0x73, 0x73, 0x65, 0x64, 0x0a, 0x00, 0x00, 0x4f, 0x70, 0x65, 0x6e,
+  0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74,
+  0x69, 0x6e, 0x67, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x20, 0x50, 0x61,
+  0x73, 0x73, 0x65, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x52, 0x65, 0x61, 0x64,
+  0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x63, 0x74,
+  0x6e, 0x65, 0x73, 0x73, 0x3a, 0x20, 0x50, 0x61, 0x73, 0x73, 0x65, 0x64,
+  0x0a, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x3a, 0x20, 0x70,
+  0x61, 0x73, 0x73, 0x65, 0x64, 0x0a, 0x00, 0x00
+};
+unsigned int testsuite_syscall_elf_len = 860;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/Makefile b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..34f92e723fa43f571d53cbaaddcc9329cd32cb2b
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/Makefile
@@ -0,0 +1,45 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+ELF := $(addsuffix .elf, $(NAME))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o $(ELF) $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  $(ELF)
+	@arm-miosix-eabi-objdump -Dslx $(ELF) > test.txt
+	@mx-postlinker $(ELF) --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i $(ELF) | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h
+
+clean:
+	-rm $(OBJ) crt0.o *.elf test.map test.txt
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(CXXFLAGS) $< -o $@
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/crt0.s b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..9959b317dcafd42e8cb82c896b3eef2e0205f7cc
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/crt0.s
@@ -0,0 +1,131 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * seek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+*/
+.section .text.seek
+.global seek
+.type seek, %function
+seek:
+	movs r3, #8
+	svc 0
+	bx lr
+	
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+	
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/main.c b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..042e8da868deaab072423be41a050c1193a299e2
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/main.c
@@ -0,0 +1,100 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+
+#define error(x)	(x)
+
+#define SIZE 1024
+
+int mystrlen(const char *s){
+	int result=0;
+	while(*s++) result++;
+	return result;
+}
+
+void print(const char *s){
+	write(1, s, mystrlen(s));
+}
+
+#define FILE_PATH	"foo.bin"
+
+int main(){
+	unsigned char buffer[SIZE],
+	buffer2[SIZE];
+	
+	int i = 0;
+	int fd = 0;
+	
+	for(i = 0; i < SIZE; i++)
+		buffer[i] = i;
+	
+	fd = open(FILE_PATH, O_RDWR, 0);
+	
+	if(fd != -1)
+		return error(1);
+	
+	close(fd);
+	
+	print("'Open' of non existing file: Passed\n");
+	
+	fd = open(FILE_PATH, O_RDWR|O_TRUNC, 0);
+	
+	if(fd == -1)
+		return error(2);
+	
+	if(fd >= 0 && fd <= 2)
+		return error(3);
+	
+	print("Open file: Passed\n");
+	
+	if(write(fd, buffer, SIZE) != SIZE)
+		return error(4);
+	
+	print("Write file: Passed\n");
+	
+	seek(fd, SEEK_SET, 0);
+	
+	if(read(fd, buffer2, SIZE) != SIZE)
+		return error(5);
+	
+	for(i = 0; i < SIZE; i++){
+		if(buffer[i] != buffer2[i])
+			return error(6);
+	}
+	
+	print("Read: Passed\n");
+	
+	if(close(fd) != 0)
+		return error(7);
+	
+	print("close: Passed\n");
+	
+	fd = open(FILE_PATH, O_RDWR);
+	
+	if(fd < 2)
+		return error(8);
+	
+	print("Open of an existing file: Passed\n");
+	
+	if(read(fd, buffer2, SIZE) != SIZE)
+		return error(9);
+	
+	for(i = 0; i < SIZE; i++){
+		if(buffer[i] != buffer2[i])
+			return error(10);
+	}
+	
+	print("Read data corectness: Passed\n");
+	
+	if(close(fd))
+		return error(11);
+	
+	print("close: passed\n");
+	
+	return 0;
+}
\ No newline at end of file
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/miosix.ld b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/prog3.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/prog3.h
new file mode 100644
index 0000000000000000000000000000000000000000..9da3e20b11c45059b60ad04de99553c35c631c7b
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/prog3.h
@@ -0,0 +1,75 @@
+const unsigned char __attribute__((aligned(8))) testsuite_syscall_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0xbe, 0x01, 0x00, 0x00,
+  0xbe, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x04, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0x64, 0x02, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x10, 0xf8,
+  0x00, 0xf0, 0xca, 0xf8, 0x08, 0xb5, 0x02, 0x78, 0x01, 0x46, 0x22, 0xb1,
+  0x00, 0x22, 0x01, 0x32, 0x8b, 0x5c, 0x00, 0x2b, 0xfb, 0xd1, 0x01, 0x20,
+  0x00, 0xf0, 0xc9, 0xf8, 0x08, 0xbd, 0x00, 0xbf, 0x2d, 0xe9, 0xf0, 0x45,
+  0xad, 0xf5, 0x00, 0x6d, 0x81, 0xb0, 0x00, 0x24, 0x0d, 0xf5, 0x80, 0x65,
+  0x2c, 0x55, 0x01, 0x34, 0xb4, 0xf5, 0x80, 0x6f, 0xfa, 0xd1, 0x4e, 0x4f,
+  0x02, 0x21, 0x09, 0xeb, 0x07, 0x06, 0x00, 0x22, 0x30, 0x46, 0x00, 0xf0,
+  0xa9, 0xf8, 0xb0, 0xf1, 0xff, 0x3f, 0x05, 0xd0, 0x01, 0x20, 0x01, 0xb0,
+  0x0d, 0xf5, 0x00, 0x6d, 0xbd, 0xe8, 0xf0, 0x85, 0x00, 0xf0, 0xa1, 0xf8,
+  0x45, 0x48, 0x48, 0x44, 0xff, 0xf7, 0xce, 0xff, 0x30, 0x46, 0x00, 0x22,
+  0x40, 0xf2, 0x02, 0x41, 0x00, 0xf0, 0x94, 0xf8, 0xb0, 0xf1, 0xff, 0x3f,
+  0x06, 0x46, 0x11, 0xd0, 0x02, 0x28, 0x01, 0xd8, 0x03, 0x20, 0xe6, 0xe7,
+  0x3d, 0x48, 0x48, 0x44, 0xff, 0xf7, 0xbc, 0xff, 0x30, 0x46, 0x29, 0x46,
+  0x22, 0x46, 0x00, 0xf0, 0x8c, 0xf8, 0xb0, 0xf5, 0x80, 0x6f, 0x03, 0xd0,
+  0x04, 0x20, 0xd8, 0xe7, 0x02, 0x20, 0xd6, 0xe7, 0x36, 0x48, 0xe8, 0x46,
+  0x48, 0x44, 0xff, 0xf7, 0xab, 0xff, 0x00, 0x21, 0x0a, 0x46, 0x30, 0x46,
+  0x00, 0xf0, 0x78, 0xf8, 0x30, 0x46, 0x69, 0x46, 0x22, 0x46, 0x00, 0xf0,
+  0x79, 0xf8, 0xb0, 0xf5, 0x80, 0x6f, 0x01, 0xd0, 0x05, 0x20, 0xc2, 0xe7,
+  0x4f, 0xf0, 0x00, 0x0a, 0x02, 0xe0, 0xba, 0xf5, 0x80, 0x6f, 0x09, 0xd0,
+  0x15, 0xf8, 0x0a, 0x20, 0x18, 0xf8, 0x0a, 0x30, 0x0a, 0xf1, 0x01, 0x0a,
+  0x9a, 0x42, 0xf4, 0xd0, 0x06, 0x20, 0xb2, 0xe7, 0x25, 0x48, 0x48, 0x44,
+  0xff, 0xf7, 0x88, 0xff, 0x30, 0x46, 0x00, 0xf0, 0x54, 0xf8, 0x06, 0x46,
+  0x08, 0xb1, 0x07, 0x20, 0xa7, 0xe7, 0x21, 0x48, 0x48, 0x44, 0xff, 0xf7,
+  0x7d, 0xff, 0x02, 0x21, 0x09, 0xeb, 0x07, 0x00, 0x00, 0xf0, 0x44, 0xf8,
+  0x01, 0x28, 0x04, 0x46, 0x0d, 0xdd, 0x1c, 0x48, 0x48, 0x44, 0xff, 0xf7,
+  0x71, 0xff, 0x20, 0x46, 0x69, 0x46, 0x52, 0x46, 0x00, 0xf0, 0x44, 0xf8,
+  0xb0, 0xf5, 0x80, 0x6f, 0x03, 0xd0, 0x09, 0x20, 0x8d, 0xe7, 0x08, 0x20,
+  0x8b, 0xe7, 0xaa, 0x5d, 0x18, 0xf8, 0x06, 0x30, 0x01, 0x36, 0x9a, 0x42,
+  0x0d, 0xd1, 0xb6, 0xf5, 0x80, 0x6f, 0xf6, 0xd1, 0x10, 0x48, 0x48, 0x44,
+  0xff, 0xf7, 0x58, 0xff, 0x20, 0x46, 0x00, 0xf0, 0x24, 0xf8, 0x04, 0x46,
+  0x18, 0xb1, 0x0b, 0x20, 0x77, 0xe7, 0x0a, 0x20, 0x75, 0xe7, 0x0b, 0x48,
+  0x48, 0x44, 0xff, 0xf7, 0x4b, 0xff, 0x20, 0x46, 0x6f, 0xe7, 0x00, 0xbf,
+  0x38, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00,
+  0x7c, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00,
+  0xb0, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00,
+  0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x07, 0x23,
+  0x00, 0xdf, 0x70, 0x47, 0x08, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x03, 0x23,
+  0x00, 0xdf, 0x70, 0x47, 0x04, 0x23, 0x00, 0xdf, 0x70, 0x47, 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, 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, 0x66, 0x6f, 0x6f, 0x2e,
+  0x62, 0x69, 0x6e, 0x00, 0x27, 0x4f, 0x70, 0x65, 0x6e, 0x27, 0x20, 0x6f,
+  0x66, 0x20, 0x6e, 0x6f, 0x6e, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74, 0x69,
+  0x6e, 0x67, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x20, 0x50, 0x61, 0x73,
+  0x73, 0x65, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x70, 0x65, 0x6e,
+  0x20, 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x20, 0x50, 0x61, 0x73, 0x73, 0x65,
+  0x64, 0x0a, 0x00, 0x00, 0x57, 0x72, 0x69, 0x74, 0x65, 0x20, 0x66, 0x69,
+  0x6c, 0x65, 0x3a, 0x20, 0x50, 0x61, 0x73, 0x73, 0x65, 0x64, 0x0a, 0x00,
+  0x52, 0x65, 0x61, 0x64, 0x3a, 0x20, 0x50, 0x61, 0x73, 0x73, 0x65, 0x64,
+  0x0a, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x3a, 0x20, 0x50,
+  0x61, 0x73, 0x73, 0x65, 0x64, 0x0a, 0x00, 0x00, 0x4f, 0x70, 0x65, 0x6e,
+  0x20, 0x6f, 0x66, 0x20, 0x61, 0x6e, 0x20, 0x65, 0x78, 0x69, 0x73, 0x74,
+  0x69, 0x6e, 0x67, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x3a, 0x20, 0x50, 0x61,
+  0x73, 0x73, 0x65, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x52, 0x65, 0x61, 0x64,
+  0x20, 0x64, 0x61, 0x74, 0x61, 0x20, 0x63, 0x6f, 0x72, 0x65, 0x63, 0x74,
+  0x6e, 0x65, 0x73, 0x73, 0x3a, 0x20, 0x50, 0x61, 0x73, 0x73, 0x65, 0x64,
+  0x0a, 0x00, 0x00, 0x00, 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x3a, 0x20, 0x70,
+  0x61, 0x73, 0x73, 0x65, 0x64, 0x0a, 0x00, 0x00
+};
+unsigned int testsuite_syscall_elf_len = 860;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/test.txt b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..eeef106f614c98c239a761e51d2c1d1efc3c55fc
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall/test.txt
@@ -0,0 +1,365 @@
+
+testsuite_syscall.elf:     file format elf32-littlearm
+testsuite_syscall.elf
+architecture: arm, flags 0x00000050:
+HAS_SYMS, DYNAMIC
+start address 0x00000099
+
+Program Header:
+    LOAD off    0x00000098 vaddr 0x00000098 paddr 0x00000098 align 2**3
+         filesz 0x000001be memsz 0x000001be flags r-x
+    LOAD off    0x00000258 vaddr 0x10000000 paddr 0x10000000 align 2**3
+         filesz 0x00000104 memsz 0x00000104 flags rw-
+ DYNAMIC off    0x00000264 vaddr 0x1000000c paddr 0x1000000c align 2**2
+         filesz 0x00000028 memsz 0x00000028 flags rw-
+
+Dynamic Section:
+  DEBUG                0x00000000
+private flags = 5000002: [Version5 EABI] [has entry point]
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .text         000001be  00000098  00000098  00000098  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+  1 .got          0000000c  10000000  10000000  00000258  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  2 .dynamic      00000028  1000000c  1000000c  00000264  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  3 .rodata       000000cc  10000038  10000038  00000290  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, DATA
+SYMBOL TABLE:
+00000098 l    d  .text	00000000 .text
+10000000 l    d  .got	00000000 .got
+1000000c l    d  .dynamic	00000000 .dynamic
+10000038 l    d  .rodata	00000000 .rodata
+00000000 l    df *ABS*	00000000 main.c
+1000000c l     O *ABS*	00000000 _DYNAMIC
+10000000 l     O *ABS*	00000000 _GLOBAL_OFFSET_TABLE_
+000000a0 g     F .text	0000001a print
+0000024a g     F .text	00000000 write
+00000098 g     F .text	00000000 _start
+00000250 g     F .text	00000000 read
+000000bc g     F .text	00000178 main
+00000244 g     F .text	00000000 seek
+00000234 g     F .text	00000000 _exit
+00000238 g     F .text	00000000 open
+0000023e g     F .text	00000000 close
+
+
+Contents of section .text:
+ 0098 00f010f8 00f0caf8 08b50278 014622b1  ...........x.F".
+ 00a8 00220132 8b5c002b fbd10120 00f0c9f8  .".2.\.+... ....
+ 00b8 08bd00bf 2de9f045 adf5006d 81b00024  ....-..E...m...$
+ 00c8 0df58065 2c550134 b4f5806f fad14e4f  ...e,U.4...o..NO
+ 00d8 022109eb 07060022 304600f0 a9f8b0f1  .!....."0F......
+ 00e8 ff3f05d0 012001b0 0df5006d bde8f085  .?... .....m....
+ 00f8 00f0a1f8 45484844 fff7ceff 30460022  ....EHHD....0F."
+ 0108 40f20241 00f094f8 b0f1ff3f 064611d0  @..A.......?.F..
+ 0118 022801d8 0320e6e7 3d484844 fff7bcff  .(... ..=HHD....
+ 0128 30462946 224600f0 8cf8b0f5 806f03d0  0F)F"F.......o..
+ 0138 0420d8e7 0220d6e7 3648e846 4844fff7  . ... ..6H.FHD..
+ 0148 abff0021 0a463046 00f078f8 30466946  ...!.F0F..x.0FiF
+ 0158 224600f0 79f8b0f5 806f01d0 0520c2e7  "F..y....o... ..
+ 0168 4ff0000a 02e0baf5 806f09d0 15f80a20  O........o..... 
+ 0178 18f80a30 0af1010a 9a42f4d0 0620b2e7  ...0.....B... ..
+ 0188 25484844 fff788ff 304600f0 54f80646  %HHD....0F..T..F
+ 0198 08b10720 a7e72148 4844fff7 7dff0221  ... ..!HHD..}..!
+ 01a8 09eb0700 00f044f8 01280446 0ddd1c48  ......D..(.F...H
+ 01b8 4844fff7 71ff2046 69465246 00f044f8  HD..q. FiFRF..D.
+ 01c8 b0f5806f 03d00920 8de70820 8be7aa5d  ...o... ... ...]
+ 01d8 18f80630 01369a42 0dd1b6f5 806ff6d1  ...0.6.B.....o..
+ 01e8 10484844 fff758ff 204600f0 24f80446  .HHD..X. F..$..F
+ 01f8 18b10b20 77e70a20 75e70b48 4844fff7  ... w.. u..HHD..
+ 0208 4bff2046 6fe700bf 38000000 40000000  K. Fo...8...@...
+ 0218 68000000 7c000000 90000000 a0000000  h...|...........
+ 0228 b0000000 d4000000 f4000000 022300df  .............#..
+ 0238 062300df 70470723 00df7047 082300df  .#..pG.#..pG.#..
+ 0248 70470323 00df7047 042300df 7047      pG.#..pG.#..pG  
+Contents of section .got:
+ 10000000 0c000010 00000000 00000000           ............    
+Contents of section .dynamic:
+ 1000000c 15000000 00000000 00000000 00000000  ................
+ 1000001c 00000000 00000000 00000000 00000000  ................
+ 1000002c 00000000 00000000                    ........        
+Contents of section .rodata:
+ 10000038 666f6f2e 62696e00 274f7065 6e27206f  foo.bin.'Open' o
+ 10000048 66206e6f 6e206578 69737469 6e672066  f non existing f
+ 10000058 696c653a 20506173 7365640a 00000000  ile: Passed.....
+ 10000068 4f70656e 2066696c 653a2050 61737365  Open file: Passe
+ 10000078 640a0000 57726974 65206669 6c653a20  d...Write file: 
+ 10000088 50617373 65640a00 52656164 3a205061  Passed..Read: Pa
+ 10000098 73736564 0a000000 636c6f73 653a2050  ssed....close: P
+ 100000a8 61737365 640a0000 4f70656e 206f6620  assed...Open of 
+ 100000b8 616e2065 78697374 696e6720 66696c65  an existing file
+ 100000c8 3a205061 73736564 0a000000 52656164  : Passed....Read
+ 100000d8 20646174 6120636f 72656374 6e657373   data corectness
+ 100000e8 3a205061 73736564 0a000000 636c6f73  : Passed....clos
+ 100000f8 653a2070 61737365 640a0000           e: passed...    
+
+Disassembly of section .text:
+
+00000098 <_start>:
+_start():
+  98:	f000 f810 	bl	bc <main>
+  9c:	f000 f8ca 	bl	234 <_exit>
+
+000000a0 <print>:
+print():
+  a0:	b508      	push	{r3, lr}
+  a2:	7802      	ldrb	r2, [r0, #0]
+  a4:	4601      	mov	r1, r0
+  a6:	b122      	cbz	r2, b2 <print+0x12>
+  a8:	2200      	movs	r2, #0
+  aa:	3201      	adds	r2, #1
+  ac:	5c8b      	ldrb	r3, [r1, r2]
+  ae:	2b00      	cmp	r3, #0
+  b0:	d1fb      	bne.n	aa <print+0xa>
+  b2:	2001      	movs	r0, #1
+  b4:	f000 f8c9 	bl	24a <write>
+  b8:	bd08      	pop	{r3, pc}
+  ba:	bf00      	nop
+
+000000bc <main>:
+main():
+  bc:	e92d 45f0 	stmdb	sp!, {r4, r5, r6, r7, r8, sl, lr}
+  c0:	f5ad 6d00 	sub.w	sp, sp, #2048	; 0x800
+  c4:	b081      	sub	sp, #4
+  c6:	2400      	movs	r4, #0
+  c8:	f50d 6580 	add.w	r5, sp, #1024	; 0x400
+  cc:	552c      	strb	r4, [r5, r4]
+  ce:	3401      	adds	r4, #1
+  d0:	f5b4 6f80 	cmp.w	r4, #1024	; 0x400
+  d4:	d1fa      	bne.n	cc <main+0x10>
+  d6:	4f4e      	ldr	r7, [pc, #312]	; (210 <main+0x154>)
+  d8:	2102      	movs	r1, #2
+  da:	eb09 0607 	add.w	r6, r9, r7
+  de:	2200      	movs	r2, #0
+  e0:	4630      	mov	r0, r6
+  e2:	f000 f8a9 	bl	238 <open>
+  e6:	f1b0 3fff 	cmp.w	r0, #4294967295	; 0xffffffff
+  ea:	d005      	beq.n	f8 <main+0x3c>
+  ec:	2001      	movs	r0, #1
+  ee:	b001      	add	sp, #4
+  f0:	f50d 6d00 	add.w	sp, sp, #2048	; 0x800
+  f4:	e8bd 85f0 	ldmia.w	sp!, {r4, r5, r6, r7, r8, sl, pc}
+  f8:	f000 f8a1 	bl	23e <close>
+  fc:	4845      	ldr	r0, [pc, #276]	; (214 <main+0x158>)
+  fe:	4448      	add	r0, r9
+ 100:	f7ff ffce 	bl	a0 <print>
+ 104:	4630      	mov	r0, r6
+ 106:	2200      	movs	r2, #0
+ 108:	f240 4102 	movw	r1, #1026	; 0x402
+ 10c:	f000 f894 	bl	238 <open>
+ 110:	f1b0 3fff 	cmp.w	r0, #4294967295	; 0xffffffff
+ 114:	4606      	mov	r6, r0
+ 116:	d011      	beq.n	13c <main+0x80>
+ 118:	2802      	cmp	r0, #2
+ 11a:	d801      	bhi.n	120 <main+0x64>
+ 11c:	2003      	movs	r0, #3
+ 11e:	e7e6      	b.n	ee <main+0x32>
+ 120:	483d      	ldr	r0, [pc, #244]	; (218 <main+0x15c>)
+ 122:	4448      	add	r0, r9
+ 124:	f7ff ffbc 	bl	a0 <print>
+ 128:	4630      	mov	r0, r6
+ 12a:	4629      	mov	r1, r5
+ 12c:	4622      	mov	r2, r4
+ 12e:	f000 f88c 	bl	24a <write>
+ 132:	f5b0 6f80 	cmp.w	r0, #1024	; 0x400
+ 136:	d003      	beq.n	140 <main+0x84>
+ 138:	2004      	movs	r0, #4
+ 13a:	e7d8      	b.n	ee <main+0x32>
+ 13c:	2002      	movs	r0, #2
+ 13e:	e7d6      	b.n	ee <main+0x32>
+ 140:	4836      	ldr	r0, [pc, #216]	; (21c <main+0x160>)
+ 142:	46e8      	mov	r8, sp
+ 144:	4448      	add	r0, r9
+ 146:	f7ff ffab 	bl	a0 <print>
+ 14a:	2100      	movs	r1, #0
+ 14c:	460a      	mov	r2, r1
+ 14e:	4630      	mov	r0, r6
+ 150:	f000 f878 	bl	244 <seek>
+ 154:	4630      	mov	r0, r6
+ 156:	4669      	mov	r1, sp
+ 158:	4622      	mov	r2, r4
+ 15a:	f000 f879 	bl	250 <read>
+ 15e:	f5b0 6f80 	cmp.w	r0, #1024	; 0x400
+ 162:	d001      	beq.n	168 <main+0xac>
+ 164:	2005      	movs	r0, #5
+ 166:	e7c2      	b.n	ee <main+0x32>
+ 168:	f04f 0a00 	mov.w	sl, #0
+ 16c:	e002      	b.n	174 <main+0xb8>
+ 16e:	f5ba 6f80 	cmp.w	sl, #1024	; 0x400
+ 172:	d009      	beq.n	188 <main+0xcc>
+ 174:	f815 200a 	ldrb.w	r2, [r5, sl]
+ 178:	f818 300a 	ldrb.w	r3, [r8, sl]
+ 17c:	f10a 0a01 	add.w	sl, sl, #1
+ 180:	429a      	cmp	r2, r3
+ 182:	d0f4      	beq.n	16e <main+0xb2>
+ 184:	2006      	movs	r0, #6
+ 186:	e7b2      	b.n	ee <main+0x32>
+ 188:	4825      	ldr	r0, [pc, #148]	; (220 <main+0x164>)
+ 18a:	4448      	add	r0, r9
+ 18c:	f7ff ff88 	bl	a0 <print>
+ 190:	4630      	mov	r0, r6
+ 192:	f000 f854 	bl	23e <close>
+ 196:	4606      	mov	r6, r0
+ 198:	b108      	cbz	r0, 19e <main+0xe2>
+ 19a:	2007      	movs	r0, #7
+ 19c:	e7a7      	b.n	ee <main+0x32>
+ 19e:	4821      	ldr	r0, [pc, #132]	; (224 <main+0x168>)
+ 1a0:	4448      	add	r0, r9
+ 1a2:	f7ff ff7d 	bl	a0 <print>
+ 1a6:	2102      	movs	r1, #2
+ 1a8:	eb09 0007 	add.w	r0, r9, r7
+ 1ac:	f000 f844 	bl	238 <open>
+ 1b0:	2801      	cmp	r0, #1
+ 1b2:	4604      	mov	r4, r0
+ 1b4:	dd0d      	ble.n	1d2 <main+0x116>
+ 1b6:	481c      	ldr	r0, [pc, #112]	; (228 <main+0x16c>)
+ 1b8:	4448      	add	r0, r9
+ 1ba:	f7ff ff71 	bl	a0 <print>
+ 1be:	4620      	mov	r0, r4
+ 1c0:	4669      	mov	r1, sp
+ 1c2:	4652      	mov	r2, sl
+ 1c4:	f000 f844 	bl	250 <read>
+ 1c8:	f5b0 6f80 	cmp.w	r0, #1024	; 0x400
+ 1cc:	d003      	beq.n	1d6 <main+0x11a>
+ 1ce:	2009      	movs	r0, #9
+ 1d0:	e78d      	b.n	ee <main+0x32>
+ 1d2:	2008      	movs	r0, #8
+ 1d4:	e78b      	b.n	ee <main+0x32>
+ 1d6:	5daa      	ldrb	r2, [r5, r6]
+ 1d8:	f818 3006 	ldrb.w	r3, [r8, r6]
+ 1dc:	3601      	adds	r6, #1
+ 1de:	429a      	cmp	r2, r3
+ 1e0:	d10d      	bne.n	1fe <main+0x142>
+ 1e2:	f5b6 6f80 	cmp.w	r6, #1024	; 0x400
+ 1e6:	d1f6      	bne.n	1d6 <main+0x11a>
+ 1e8:	4810      	ldr	r0, [pc, #64]	; (22c <main+0x170>)
+ 1ea:	4448      	add	r0, r9
+ 1ec:	f7ff ff58 	bl	a0 <print>
+ 1f0:	4620      	mov	r0, r4
+ 1f2:	f000 f824 	bl	23e <close>
+ 1f6:	4604      	mov	r4, r0
+ 1f8:	b118      	cbz	r0, 202 <main+0x146>
+ 1fa:	200b      	movs	r0, #11
+ 1fc:	e777      	b.n	ee <main+0x32>
+ 1fe:	200a      	movs	r0, #10
+ 200:	e775      	b.n	ee <main+0x32>
+ 202:	480b      	ldr	r0, [pc, #44]	; (230 <main+0x174>)
+ 204:	4448      	add	r0, r9
+ 206:	f7ff ff4b 	bl	a0 <print>
+ 20a:	4620      	mov	r0, r4
+ 20c:	e76f      	b.n	ee <main+0x32>
+ 20e:	bf00      	nop
+ 210:	00000038 	andeq	r0, r0, r8, lsr r0
+ 214:	00000040 	andeq	r0, r0, r0, asr #32
+ 218:	00000068 	andeq	r0, r0, r8, rrx
+ 21c:	0000007c 	andeq	r0, r0, ip, ror r0
+ 220:	00000090 	muleq	r0, r0, r0
+ 224:	000000a0 	andeq	r0, r0, r0, lsr #1
+ 228:	000000b0 	strheq	r0, [r0], -r0	; <UNPREDICTABLE>
+ 22c:	000000d4 	ldrdeq	r0, [r0], -r4
+ 230:	000000f4 	strdeq	r0, [r0], -r4
+
+00000234 <_exit>:
+_exit():
+ 234:	2302      	movs	r3, #2
+ 236:	df00      	svc	0
+
+00000238 <open>:
+open():
+ 238:	2306      	movs	r3, #6
+ 23a:	df00      	svc	0
+ 23c:	4770      	bx	lr
+
+0000023e <close>:
+close():
+ 23e:	2307      	movs	r3, #7
+ 240:	df00      	svc	0
+ 242:	4770      	bx	lr
+
+00000244 <seek>:
+seek():
+ 244:	2308      	movs	r3, #8
+ 246:	df00      	svc	0
+ 248:	4770      	bx	lr
+
+0000024a <write>:
+write():
+ 24a:	2303      	movs	r3, #3
+ 24c:	df00      	svc	0
+ 24e:	4770      	bx	lr
+
+00000250 <read>:
+read():
+ 250:	2304      	movs	r3, #4
+ 252:	df00      	svc	0
+ 254:	4770      	bx	lr
+
+Disassembly of section .got:
+
+10000000 <.got>:
+10000000:	1000000c 	andne	r0, r0, ip
+	...
+
+Disassembly of section .dynamic:
+
+1000000c <.dynamic>:
+1000000c:	00000015 	andeq	r0, r0, r5, lsl r0
+	...
+
+Disassembly of section .rodata:
+
+10000038 <.rodata>:
+10000038:	2e6f6f66 	cdpcs	15, 6, cr6, cr15, cr6, {3}
+1000003c:	006e6962 	rsbeq	r6, lr, r2, ror #18
+10000040:	65704f27 	ldrbvs	r4, [r0, #-3879]!	; 0xf27
+10000044:	6f20276e 	svcvs	0x0020276e
+10000048:	6f6e2066 	svcvs	0x006e2066
+1000004c:	7865206e 	stmdavc	r5!, {r1, r2, r3, r5, r6, sp}^
+10000050:	69747369 	ldmdbvs	r4!, {r0, r3, r5, r6, r8, r9, ip, sp, lr}^
+10000054:	6620676e 	strtvs	r6, [r0], -lr, ror #14
+10000058:	3a656c69 	bcc	1195b204 <_DYNAMIC+0x195b1f8>
+1000005c:	73615020 	cmnvc	r1, #32
+10000060:	0a646573 	beq	11919634 <_DYNAMIC+0x1919628>
+10000064:	00000000 	andeq	r0, r0, r0
+10000068:	6e65704f 	cdpvs	0, 6, cr7, cr5, cr15, {2}
+1000006c:	6c696620 	stclvs	6, cr6, [r9], #-128	; 0xffffff80
+10000070:	50203a65 	eorpl	r3, r0, r5, ror #20
+10000074:	65737361 	ldrbvs	r7, [r3, #-865]!	; 0x361
+10000078:	00000a64 	andeq	r0, r0, r4, ror #20
+1000007c:	74697257 	strbtvc	r7, [r9], #-599	; 0x257
+10000080:	69662065 	stmdbvs	r6!, {r0, r2, r5, r6, sp}^
+10000084:	203a656c 	eorscs	r6, sl, ip, ror #10
+10000088:	73736150 	cmnvc	r3, #20
+1000008c:	000a6465 	andeq	r6, sl, r5, ror #8
+10000090:	64616552 	strbtvs	r6, [r1], #-1362	; 0x552
+10000094:	6150203a 	cmpvs	r0, sl, lsr r0
+10000098:	64657373 	strbtvs	r7, [r5], #-883	; 0x373
+1000009c:	0000000a 	andeq	r0, r0, sl
+100000a0:	736f6c63 	cmnvc	pc, #25344	; 0x6300
+100000a4:	50203a65 	eorpl	r3, r0, r5, ror #20
+100000a8:	65737361 	ldrbvs	r7, [r3, #-865]!	; 0x361
+100000ac:	00000a64 	andeq	r0, r0, r4, ror #20
+100000b0:	6e65704f 	cdpvs	0, 6, cr7, cr5, cr15, {2}
+100000b4:	20666f20 	rsbcs	r6, r6, r0, lsr #30
+100000b8:	65206e61 	strvs	r6, [r0, #-3681]!	; 0xe61
+100000bc:	74736978 	ldrbtvc	r6, [r3], #-2424	; 0x978
+100000c0:	20676e69 	rsbcs	r6, r7, r9, ror #28
+100000c4:	656c6966 	strbvs	r6, [ip, #-2406]!	; 0x966
+100000c8:	6150203a 	cmpvs	r0, sl, lsr r0
+100000cc:	64657373 	strbtvs	r7, [r5], #-883	; 0x373
+100000d0:	0000000a 	andeq	r0, r0, sl
+100000d4:	64616552 	strbtvs	r6, [r1], #-1362	; 0x552
+100000d8:	74616420 	strbtvc	r6, [r1], #-1056	; 0x420
+100000dc:	6f632061 	svcvs	0x00632061
+100000e0:	74636572 	strbtvc	r6, [r3], #-1394	; 0x572
+100000e4:	7373656e 	cmnvc	r3, #461373440	; 0x1b800000
+100000e8:	6150203a 	cmpvs	r0, sl, lsr r0
+100000ec:	64657373 	strbtvs	r7, [r5], #-883	; 0x373
+100000f0:	0000000a 	andeq	r0, r0, sl
+100000f4:	736f6c63 	cmnvc	pc, #25344	; 0x6300
+100000f8:	70203a65 	eorvc	r3, r0, r5, ror #20
+100000fc:	65737361 	ldrbvs	r7, [r3, #-865]!	; 0x361
+10000100:	00000a64 	andeq	r0, r0, r4, ror #20
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d53a3c2674f0ed8b1dfa50a61f25dc6980e5ecd
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu.h
@@ -0,0 +1,24 @@
+const unsigned char __attribute__((aligned(8))) testsuite_syscall_mpu_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
+  0x26, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xcc, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x0a, 0xf8, 0x00, 0x20, 0x08, 0xb5, 0x40, 0xf2, 0x02, 0x41,
+  0x02, 0x46, 0x00, 0xf0, 0x05, 0xf8, 0x00, 0x20, 0x08, 0xbd, 0x00, 0xbf,
+  0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf, 0x70, 0x47, 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, 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
+};
+unsigned int testsuite_syscall_mpu_elf_len = 244;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open.h
new file mode 100644
index 0000000000000000000000000000000000000000..796bcc6141a3232cafa7ff58816afcda0247b6e6
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open.h
@@ -0,0 +1,24 @@
+const unsigned char __attribute__((aligned(8))) testsuite_syscall_mpu_open_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
+  0x26, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xcc, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x0a, 0xf8, 0x00, 0x20, 0x08, 0xb5, 0x40, 0xf2, 0x02, 0x41,
+  0x02, 0x46, 0x00, 0xf0, 0x05, 0xf8, 0x00, 0x20, 0x08, 0xbd, 0x00, 0xbf,
+  0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf, 0x70, 0x47, 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, 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
+};
+unsigned int testsuite_syscall_mpu_open_elf_len = 244;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/Makefile b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..34f92e723fa43f571d53cbaaddcc9329cd32cb2b
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/Makefile
@@ -0,0 +1,45 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+ELF := $(addsuffix .elf, $(NAME))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o $(ELF) $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  $(ELF)
+	@arm-miosix-eabi-objdump -Dslx $(ELF) > test.txt
+	@mx-postlinker $(ELF) --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i $(ELF) | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h
+
+clean:
+	-rm $(OBJ) crt0.o *.elf test.map test.txt
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(CXXFLAGS) $< -o $@
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/crt0.s b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..9959b317dcafd42e8cb82c896b3eef2e0205f7cc
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/crt0.s
@@ -0,0 +1,131 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * seek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+*/
+.section .text.seek
+.global seek
+.type seek, %function
+seek:
+	movs r3, #8
+	svc 0
+	bx lr
+	
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+	
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/main.c b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..376be3d7764c2a6a6b2c7bc3e7cd4aa01de26df5
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/main.c
@@ -0,0 +1,13 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main(){
+	int fd = open(0x00000000, O_RDWR|O_TRUNC, 0);
+	return 0;
+}
+
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/miosix.ld b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/prog3.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/prog3.h
new file mode 100644
index 0000000000000000000000000000000000000000..796bcc6141a3232cafa7ff58816afcda0247b6e6
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/prog3.h
@@ -0,0 +1,24 @@
+const unsigned char __attribute__((aligned(8))) testsuite_syscall_mpu_open_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00,
+  0x26, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x34, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xcc, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x0a, 0xf8, 0x00, 0x20, 0x08, 0xb5, 0x40, 0xf2, 0x02, 0x41,
+  0x02, 0x46, 0x00, 0xf0, 0x05, 0xf8, 0x00, 0x20, 0x08, 0xbd, 0x00, 0xbf,
+  0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf, 0x70, 0x47, 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, 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
+};
+unsigned int testsuite_syscall_mpu_open_elf_len = 244;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/test.txt b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1171c3914a8e6585b7dabe399e52f08450f9b670
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_open/test.txt
@@ -0,0 +1,91 @@
+
+testsuite_syscall_mpu_open.elf:     file format elf32-littlearm
+testsuite_syscall_mpu_open.elf
+architecture: arm, flags 0x00000050:
+HAS_SYMS, DYNAMIC
+start address 0x00000099
+
+Program Header:
+    LOAD off    0x00000098 vaddr 0x00000098 paddr 0x00000098 align 2**3
+         filesz 0x00000026 memsz 0x00000026 flags r-x
+    LOAD off    0x000000c0 vaddr 0x10000000 paddr 0x10000000 align 2**2
+         filesz 0x00000034 memsz 0x00000034 flags rw-
+ DYNAMIC off    0x000000cc vaddr 0x1000000c paddr 0x1000000c align 2**2
+         filesz 0x00000028 memsz 0x00000028 flags rw-
+
+Dynamic Section:
+  DEBUG                0x00000000
+private flags = 5000002: [Version5 EABI] [has entry point]
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .text         00000026  00000098  00000098  00000098  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+  1 .got          0000000c  10000000  10000000  000000c0  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  2 .dynamic      00000028  1000000c  1000000c  000000cc  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+SYMBOL TABLE:
+00000098 l    d  .text	00000000 .text
+10000000 l    d  .got	00000000 .got
+1000000c l    d  .dynamic	00000000 .dynamic
+00000000 l    df *ABS*	00000000 main.c
+1000000c l     O *ABS*	00000000 _DYNAMIC
+10000000 l     O *ABS*	00000000 _GLOBAL_OFFSET_TABLE_
+00000098 g     F .text	00000000 _start
+000000a0 g     F .text	00000012 main
+000000b4 g     F .text	00000000 _exit
+000000b8 g     F .text	00000000 open
+
+
+Contents of section .text:
+ 0098 00f002f8 00f00af8 002008b5 40f20241  ......... ..@..A
+ 00a8 024600f0 05f80020 08bd00bf 022300df  .F..... .....#..
+ 00b8 062300df 7047                        .#..pG          
+Contents of section .got:
+ 10000000 0c000010 00000000 00000000           ............    
+Contents of section .dynamic:
+ 1000000c 15000000 00000000 00000000 00000000  ................
+ 1000001c 00000000 00000000 00000000 00000000  ................
+ 1000002c 00000000 00000000                    ........        
+
+Disassembly of section .text:
+
+00000098 <_start>:
+_start():
+  98:	f000 f802 	bl	a0 <main>
+  9c:	f000 f80a 	bl	b4 <_exit>
+
+000000a0 <main>:
+main():
+  a0:	2000      	movs	r0, #0
+  a2:	b508      	push	{r3, lr}
+  a4:	f240 4102 	movw	r1, #1026	; 0x402
+  a8:	4602      	mov	r2, r0
+  aa:	f000 f805 	bl	b8 <open>
+  ae:	2000      	movs	r0, #0
+  b0:	bd08      	pop	{r3, pc}
+  b2:	bf00      	nop
+
+000000b4 <_exit>:
+_exit():
+  b4:	2302      	movs	r3, #2
+  b6:	df00      	svc	0
+
+000000b8 <open>:
+open():
+  b8:	2306      	movs	r3, #6
+  ba:	df00      	svc	0
+  bc:	4770      	bx	lr
+
+Disassembly of section .got:
+
+10000000 <.got>:
+10000000:	1000000c 	andne	r0, r0, ip
+	...
+
+Disassembly of section .dynamic:
+
+1000000c <.dynamic>:
+1000000c:	00000015 	andeq	r0, r0, r5, lsl r0
+	...
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read.h
new file mode 100644
index 0000000000000000000000000000000000000000..ac0c259590b4ad83125d5b755bbd2582930fa5d5
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read.h
@@ -0,0 +1,26 @@
+const unsigned char __attribute__((aligned(8))) testsuite_syscall_mpu_read_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
+  0x38, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xdc, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x10, 0xf8, 0x06, 0x48, 0x08, 0xb5, 0x00, 0x22, 0x40, 0xf2,
+  0x02, 0x41, 0x48, 0x44, 0x00, 0xf0, 0x0a, 0xf8, 0x00, 0x21, 0x0a, 0x22,
+  0x00, 0xf0, 0x09, 0xf8, 0x00, 0x20, 0x08, 0xbd, 0x38, 0x00, 0x00, 0x00,
+  0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x04, 0x23,
+  0x00, 0xdf, 0x70, 0x47, 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, 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,
+  0x2f, 0x72, 0x64, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x78, 0x74, 0x00
+};
+unsigned int testsuite_syscall_mpu_read_elf_len = 276;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/Makefile b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..34f92e723fa43f571d53cbaaddcc9329cd32cb2b
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/Makefile
@@ -0,0 +1,45 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+ELF := $(addsuffix .elf, $(NAME))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o $(ELF) $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  $(ELF)
+	@arm-miosix-eabi-objdump -Dslx $(ELF) > test.txt
+	@mx-postlinker $(ELF) --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i $(ELF) | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h
+
+clean:
+	-rm $(OBJ) crt0.o *.elf test.map test.txt
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(CXXFLAGS) $< -o $@
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/crt0.s b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..9959b317dcafd42e8cb82c896b3eef2e0205f7cc
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/crt0.s
@@ -0,0 +1,131 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * seek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+*/
+.section .text.seek
+.global seek
+.type seek, %function
+seek:
+	movs r3, #8
+	svc 0
+	bx lr
+	
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+	
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/main.c b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..f442ac5449df51a65993feb47b9a2f8570d32797
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/main.c
@@ -0,0 +1,15 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main(){
+	int fd = open("/rdtest.txt", O_RDWR|O_TRUNC, 0);
+	
+	read(fd, 0x00, 10);
+	return 0;
+}
+
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/miosix.ld b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/prog3.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/prog3.h
new file mode 100644
index 0000000000000000000000000000000000000000..ac0c259590b4ad83125d5b755bbd2582930fa5d5
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/prog3.h
@@ -0,0 +1,26 @@
+const unsigned char __attribute__((aligned(8))) testsuite_syscall_mpu_read_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
+  0x38, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xdc, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x10, 0xf8, 0x06, 0x48, 0x08, 0xb5, 0x00, 0x22, 0x40, 0xf2,
+  0x02, 0x41, 0x48, 0x44, 0x00, 0xf0, 0x0a, 0xf8, 0x00, 0x21, 0x0a, 0x22,
+  0x00, 0xf0, 0x09, 0xf8, 0x00, 0x20, 0x08, 0xbd, 0x38, 0x00, 0x00, 0x00,
+  0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x04, 0x23,
+  0x00, 0xdf, 0x70, 0x47, 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, 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,
+  0x2f, 0x72, 0x64, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x78, 0x74, 0x00
+};
+unsigned int testsuite_syscall_mpu_read_elf_len = 276;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/test.txt b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..29fe458254a092dc3ed536111dd02b20df4f6bfc
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_read/test.txt
@@ -0,0 +1,115 @@
+
+testsuite_syscall_mpu_read.elf:     file format elf32-littlearm
+testsuite_syscall_mpu_read.elf
+architecture: arm, flags 0x00000050:
+HAS_SYMS, DYNAMIC
+start address 0x00000099
+
+Program Header:
+    LOAD off    0x00000098 vaddr 0x00000098 paddr 0x00000098 align 2**3
+         filesz 0x00000038 memsz 0x00000038 flags r-x
+    LOAD off    0x000000d0 vaddr 0x10000000 paddr 0x10000000 align 2**3
+         filesz 0x00000044 memsz 0x00000044 flags rw-
+ DYNAMIC off    0x000000dc vaddr 0x1000000c paddr 0x1000000c align 2**2
+         filesz 0x00000028 memsz 0x00000028 flags rw-
+
+Dynamic Section:
+  DEBUG                0x00000000
+private flags = 5000002: [Version5 EABI] [has entry point]
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .text         00000038  00000098  00000098  00000098  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+  1 .got          0000000c  10000000  10000000  000000d0  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  2 .dynamic      00000028  1000000c  1000000c  000000dc  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  3 .rodata       0000000c  10000038  10000038  00000108  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, DATA
+SYMBOL TABLE:
+00000098 l    d  .text	00000000 .text
+10000000 l    d  .got	00000000 .got
+1000000c l    d  .dynamic	00000000 .dynamic
+10000038 l    d  .rodata	00000000 .rodata
+00000000 l    df *ABS*	00000000 main.c
+1000000c l     O *ABS*	00000000 _DYNAMIC
+10000000 l     O *ABS*	00000000 _GLOBAL_OFFSET_TABLE_
+00000098 g     F .text	00000000 _start
+000000ca g     F .text	00000000 read
+000000a0 g     F .text	00000020 main
+000000c0 g     F .text	00000000 _exit
+000000c4 g     F .text	00000000 open
+
+
+Contents of section .text:
+ 0098 00f002f8 00f010f8 064808b5 002240f2  .........H..."@.
+ 00a8 02414844 00f00af8 00210a22 00f009f8  .AHD.....!."....
+ 00b8 002008bd 38000000 022300df 062300df  . ..8....#...#..
+ 00c8 70470423 00df7047                    pG.#..pG        
+Contents of section .got:
+ 10000000 0c000010 00000000 00000000           ............    
+Contents of section .dynamic:
+ 1000000c 15000000 00000000 00000000 00000000  ................
+ 1000001c 00000000 00000000 00000000 00000000  ................
+ 1000002c 00000000 00000000                    ........        
+Contents of section .rodata:
+ 10000038 2f726474 6573742e 74787400           /rdtest.txt.    
+
+Disassembly of section .text:
+
+00000098 <_start>:
+_start():
+  98:	f000 f802 	bl	a0 <main>
+  9c:	f000 f810 	bl	c0 <_exit>
+
+000000a0 <main>:
+main():
+  a0:	4806      	ldr	r0, [pc, #24]	; (bc <main+0x1c>)
+  a2:	b508      	push	{r3, lr}
+  a4:	2200      	movs	r2, #0
+  a6:	f240 4102 	movw	r1, #1026	; 0x402
+  aa:	4448      	add	r0, r9
+  ac:	f000 f80a 	bl	c4 <open>
+  b0:	2100      	movs	r1, #0
+  b2:	220a      	movs	r2, #10
+  b4:	f000 f809 	bl	ca <read>
+  b8:	2000      	movs	r0, #0
+  ba:	bd08      	pop	{r3, pc}
+  bc:	00000038 	andeq	r0, r0, r8, lsr r0
+
+000000c0 <_exit>:
+_exit():
+  c0:	2302      	movs	r3, #2
+  c2:	df00      	svc	0
+
+000000c4 <open>:
+open():
+  c4:	2306      	movs	r3, #6
+  c6:	df00      	svc	0
+  c8:	4770      	bx	lr
+
+000000ca <read>:
+read():
+  ca:	2304      	movs	r3, #4
+  cc:	df00      	svc	0
+  ce:	4770      	bx	lr
+
+Disassembly of section .got:
+
+10000000 <.got>:
+10000000:	1000000c 	andne	r0, r0, ip
+	...
+
+Disassembly of section .dynamic:
+
+1000000c <.dynamic>:
+1000000c:	00000015 	andeq	r0, r0, r5, lsl r0
+	...
+
+Disassembly of section .rodata:
+
+10000038 <.rodata>:
+10000038:	7464722f 	strbtvc	r7, [r4], #-559	; 0x22f
+1000003c:	2e747365 	cdpcs	3, 7, cr7, cr4, cr5, {3}
+10000040:	00747874 	rsbseq	r7, r4, r4, ror r8
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write.h
new file mode 100644
index 0000000000000000000000000000000000000000..61bf80e6e882d1f6824ec89f61cf7df86ed350ac
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write.h
@@ -0,0 +1,26 @@
+const unsigned char __attribute__((aligned(8))) testsuite_syscall_mpu_write_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
+  0x38, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xdc, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x10, 0xf8, 0x06, 0x48, 0x08, 0xb5, 0x00, 0x22, 0x40, 0xf2,
+  0x02, 0x41, 0x48, 0x44, 0x00, 0xf0, 0x0a, 0xf8, 0x00, 0x21, 0x0a, 0x22,
+  0x00, 0xf0, 0x09, 0xf8, 0x00, 0x20, 0x08, 0xbd, 0x38, 0x00, 0x00, 0x00,
+  0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x03, 0x23,
+  0x00, 0xdf, 0x70, 0x47, 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, 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,
+  0x2f, 0x72, 0x64, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x78, 0x74, 0x00
+};
+unsigned int testsuite_syscall_mpu_write_elf_len = 276;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/Makefile b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..34f92e723fa43f571d53cbaaddcc9329cd32cb2b
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/Makefile
@@ -0,0 +1,45 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+ELF := $(addsuffix .elf, $(NAME))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o $(ELF) $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  $(ELF)
+	@arm-miosix-eabi-objdump -Dslx $(ELF) > test.txt
+	@mx-postlinker $(ELF) --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i $(ELF) | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h
+
+clean:
+	-rm $(OBJ) crt0.o *.elf test.map test.txt
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(CXXFLAGS) $< -o $@
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/crt0.s b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..9959b317dcafd42e8cb82c896b3eef2e0205f7cc
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/crt0.s
@@ -0,0 +1,131 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * seek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+*/
+.section .text.seek
+.global seek
+.type seek, %function
+seek:
+	movs r3, #8
+	svc 0
+	bx lr
+	
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+	
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/main.c b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..0fd7b2c1a4a40b8511bf6956af916374994689bd
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/main.c
@@ -0,0 +1,15 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+
+int main(){
+	int fd = open("/rdtest.txt", O_RDWR|O_TRUNC, 0);
+	
+	write(fd, 0x00, 10);
+	return 0;
+}
+
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/miosix.ld b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/prog3.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/prog3.h
new file mode 100644
index 0000000000000000000000000000000000000000..61bf80e6e882d1f6824ec89f61cf7df86ed350ac
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/prog3.h
@@ -0,0 +1,26 @@
+const unsigned char __attribute__((aligned(8))) testsuite_syscall_mpu_write_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
+  0x38, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xdc, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x10, 0xf8, 0x06, 0x48, 0x08, 0xb5, 0x00, 0x22, 0x40, 0xf2,
+  0x02, 0x41, 0x48, 0x44, 0x00, 0xf0, 0x0a, 0xf8, 0x00, 0x21, 0x0a, 0x22,
+  0x00, 0xf0, 0x09, 0xf8, 0x00, 0x20, 0x08, 0xbd, 0x38, 0x00, 0x00, 0x00,
+  0x02, 0x23, 0x00, 0xdf, 0x06, 0x23, 0x00, 0xdf, 0x70, 0x47, 0x03, 0x23,
+  0x00, 0xdf, 0x70, 0x47, 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, 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,
+  0x2f, 0x72, 0x64, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x78, 0x74, 0x00
+};
+unsigned int testsuite_syscall_mpu_write_elf_len = 276;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/test.txt b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..21e148eb168d529f32d617ffd97cc46308e9a61d
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_syscall_mpu_write/test.txt
@@ -0,0 +1,115 @@
+
+testsuite_syscall_mpu_write.elf:     file format elf32-littlearm
+testsuite_syscall_mpu_write.elf
+architecture: arm, flags 0x00000050:
+HAS_SYMS, DYNAMIC
+start address 0x00000099
+
+Program Header:
+    LOAD off    0x00000098 vaddr 0x00000098 paddr 0x00000098 align 2**3
+         filesz 0x00000038 memsz 0x00000038 flags r-x
+    LOAD off    0x000000d0 vaddr 0x10000000 paddr 0x10000000 align 2**3
+         filesz 0x00000044 memsz 0x00000044 flags rw-
+ DYNAMIC off    0x000000dc vaddr 0x1000000c paddr 0x1000000c align 2**2
+         filesz 0x00000028 memsz 0x00000028 flags rw-
+
+Dynamic Section:
+  DEBUG                0x00000000
+private flags = 5000002: [Version5 EABI] [has entry point]
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .text         00000038  00000098  00000098  00000098  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+  1 .got          0000000c  10000000  10000000  000000d0  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  2 .dynamic      00000028  1000000c  1000000c  000000dc  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  3 .rodata       0000000c  10000038  10000038  00000108  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, DATA
+SYMBOL TABLE:
+00000098 l    d  .text	00000000 .text
+10000000 l    d  .got	00000000 .got
+1000000c l    d  .dynamic	00000000 .dynamic
+10000038 l    d  .rodata	00000000 .rodata
+00000000 l    df *ABS*	00000000 main.c
+1000000c l     O *ABS*	00000000 _DYNAMIC
+10000000 l     O *ABS*	00000000 _GLOBAL_OFFSET_TABLE_
+000000ca g     F .text	00000000 write
+00000098 g     F .text	00000000 _start
+000000a0 g     F .text	00000020 main
+000000c0 g     F .text	00000000 _exit
+000000c4 g     F .text	00000000 open
+
+
+Contents of section .text:
+ 0098 00f002f8 00f010f8 064808b5 002240f2  .........H..."@.
+ 00a8 02414844 00f00af8 00210a22 00f009f8  .AHD.....!."....
+ 00b8 002008bd 38000000 022300df 062300df  . ..8....#...#..
+ 00c8 70470323 00df7047                    pG.#..pG        
+Contents of section .got:
+ 10000000 0c000010 00000000 00000000           ............    
+Contents of section .dynamic:
+ 1000000c 15000000 00000000 00000000 00000000  ................
+ 1000001c 00000000 00000000 00000000 00000000  ................
+ 1000002c 00000000 00000000                    ........        
+Contents of section .rodata:
+ 10000038 2f726474 6573742e 74787400           /rdtest.txt.    
+
+Disassembly of section .text:
+
+00000098 <_start>:
+_start():
+  98:	f000 f802 	bl	a0 <main>
+  9c:	f000 f810 	bl	c0 <_exit>
+
+000000a0 <main>:
+main():
+  a0:	4806      	ldr	r0, [pc, #24]	; (bc <main+0x1c>)
+  a2:	b508      	push	{r3, lr}
+  a4:	2200      	movs	r2, #0
+  a6:	f240 4102 	movw	r1, #1026	; 0x402
+  aa:	4448      	add	r0, r9
+  ac:	f000 f80a 	bl	c4 <open>
+  b0:	2100      	movs	r1, #0
+  b2:	220a      	movs	r2, #10
+  b4:	f000 f809 	bl	ca <write>
+  b8:	2000      	movs	r0, #0
+  ba:	bd08      	pop	{r3, pc}
+  bc:	00000038 	andeq	r0, r0, r8, lsr r0
+
+000000c0 <_exit>:
+_exit():
+  c0:	2302      	movs	r3, #2
+  c2:	df00      	svc	0
+
+000000c4 <open>:
+open():
+  c4:	2306      	movs	r3, #6
+  c6:	df00      	svc	0
+  c8:	4770      	bx	lr
+
+000000ca <write>:
+write():
+  ca:	2303      	movs	r3, #3
+  cc:	df00      	svc	0
+  ce:	4770      	bx	lr
+
+Disassembly of section .got:
+
+10000000 <.got>:
+10000000:	1000000c 	andne	r0, r0, ip
+	...
+
+Disassembly of section .dynamic:
+
+1000000c <.dynamic>:
+1000000c:	00000015 	andeq	r0, r0, r5, lsl r0
+	...
+
+Disassembly of section .rodata:
+
+10000038 <.rodata>:
+10000038:	7464722f 	strbtvc	r7, [r4], #-559	; 0x22f
+1000003c:	2e747365 	cdpcs	3, 7, cr7, cr4, cr5, {3}
+10000040:	00747874 	rsbseq	r7, r4, r4, ror r8
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_system.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system.h
new file mode 100644
index 0000000000000000000000000000000000000000..e263fad5b2841783c8b235aa6a87cb3ab712012d
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system.h
@@ -0,0 +1,25 @@
+const unsigned char __attribute__((aligned(8))) testsuite_system_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+  0x22, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xcc, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x08, 0xf8, 0x02, 0x48, 0x08, 0xb5, 0x48, 0x44, 0x00, 0xf0,
+  0x05, 0xf8, 0x08, 0xbd, 0x38, 0x00, 0x00, 0x00, 0x02, 0x23, 0x00, 0xdf,
+  0x09, 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, 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, 0x74, 0x65, 0x73, 0x74,
+  0x00, 0x00, 0x00, 0x00
+};
+unsigned int testsuite_system_elf_len = 256;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/Makefile b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..34f92e723fa43f571d53cbaaddcc9329cd32cb2b
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/Makefile
@@ -0,0 +1,45 @@
+##
+## Makefile for writing PROGRAMS for the Miosix embedded OS
+## TFT:Terraneo Federico Technlogies
+##
+
+SRC := \
+main.c
+
+## Replaces both "foo.cpp"-->"foo.o" and "foo.c"-->"foo.o"
+OBJ := $(addsuffix .o, $(basename $(SRC)))
+ELF := $(addsuffix .elf, $(NAME))
+
+AS  := arm-miosix-eabi-as
+CC  := arm-miosix-eabi-gcc
+CXX := arm-miosix-eabi-g++
+SZ  := arm-miosix-eabi-size
+
+AFLAGS   := -mcpu=cortex-m3 -mthumb
+CFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -ffunction-sections -O2 -Wall -c
+CXXFLAGS := $(CFLAGS)
+LFLAGS   := -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -fpie -msingle-pic-base \
+            -Wl,--gc-sections,-Map,test.map,-T./miosix.ld,-n,-pie,--spare-dynamic-tags,3 \
+            -O2 -nostdlib
+
+LINK_LIBS := -Wl,--start-group -lstdc++ -lc -lm -lgcc -Wl,--end-group
+
+all: $(OBJ) crt0.o
+	$(CXX) $(LFLAGS) -o $(ELF) $(OBJ) crt0.o $(LINK_LIBS)
+	$(SZ)  $(ELF)
+	@arm-miosix-eabi-objdump -Dslx $(ELF) > test.txt
+	@mx-postlinker $(ELF) --ramsize=16384 --stacksize=2048 --strip-sectheader
+	@xxd -i $(ELF) | sed 's/unsigned char/const unsigned char __attribute__((aligned(8)))/' > prog3.h
+
+clean:
+	-rm $(OBJ) crt0.o *.elf test.map test.txt
+
+%.o: %.s
+	$(AS) $(AFLAGS) $< -o $@
+
+%.o : %.c
+	$(CC) $(CFLAGS) $< -o $@
+
+%.o : %.cpp
+	$(CXX) $(CXXFLAGS) $< -o $@
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/crt0.s b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/crt0.s
new file mode 100644
index 0000000000000000000000000000000000000000..8dbb153d806028cd739d686a05eac59d6357eb74
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/crt0.s
@@ -0,0 +1,130 @@
+/*
+ * Startup script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+.syntax unified
+.cpu cortex-m3
+.thumb
+
+.section .text
+
+/**
+ * _start, program entry point
+ */
+.global _start
+.type _start, %function
+_start:
+	/* TODO: .ctor */
+	bl   main
+	/* TODO: .dtor */
+	bl   _exit
+
+/**
+ * _exit, terminate process
+ * \param v exit value 
+ */
+.section .text._exit
+.global _exit
+.type _exit, %function
+_exit:
+	movs r3, #2
+	svc  0
+
+/**
+ * open, open a file
+ * \param fd file descriptor
+ * \param file access mode
+ * \param xxx access permisions
+ * \return file descriptor or -1 if errors
+ */
+.section .text.open
+.global open
+.type open, %function
+open:
+	movs r3, #6
+	svc 0
+	bx lr
+
+/**
+ * close, close a file
+ * \param fd file descriptor
+ */
+.section .text.close
+.global close
+.type close, %function
+close:
+	movs r3, #7
+	svc 0
+	bx lr
+
+/**
+ * lseek
+ * \param fd file descriptor
+ * \param pos moving offset
+ * \param start position, SEEK_SET, SEEK_CUR or SEEK_END
+*/ 
+.section .text.seek
+.global seek
+.type seek, %function
+	
+	movs r3, #8
+	svc 0
+	bx lr
+
+
+/**
+ * system, fork and execture a program, blocking
+ * \param program to execute
+ */
+.section .text.system
+.global system
+.type system, %function
+system:
+	movs r3, #9
+	svc 0
+	bx lr
+/**
+ * write, write to file
+ * \param fd file descriptor
+ * \param buf data to be written
+ * \param len buffer length
+ * \return number of written bytes or -1 if errors
+ */
+.section .text.write
+.global	write
+.type	write, %function
+write:
+    movs r3, #3
+    svc  0
+    bx   lr
+
+/**
+ * read, read from file
+ * \param fd file descriptor
+ * \param buf data to be read
+ * \param len buffer length
+ * \return number of read bytes or -1 if errors
+ */
+.section .text.read
+.global	read
+.type	read, %function
+read:
+    movs r3, #4
+    svc  0
+    bx   lr
+
+/**
+ * usleep, sleep a specified number of microseconds
+ * \param us number of microseconds to sleep
+ * \return 0 on success or -1 if errors
+ */
+.section .text.usleep
+.global	usleep
+.type	usleep, %function
+usleep:
+    movs r3, #5
+    svc  0
+    bx   lr
+
+.end
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/main.c b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/main.c
new file mode 100644
index 0000000000000000000000000000000000000000..3cc4e59f29527db6947b1cae6260e76a75a53d5c
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/main.c
@@ -0,0 +1,12 @@
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(){
+	return system("test");
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/miosix.ld b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/miosix.ld
new file mode 100644
index 0000000000000000000000000000000000000000..c91c803e629040b14233a8f8251a7d9952f68910
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/miosix.ld
@@ -0,0 +1,66 @@
+/*
+ * Linker script for writing PROGRAMS for the Miosix embedded OS
+ * TFT:Terraneo Federico Technlogies
+ */
+
+OUTPUT_FORMAT("elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+
+SECTIONS
+{
+    /* Here starts the first elf segment, that stays in flash */
+    . = 0 + SIZEOF_HEADERS;
+
+    .text : ALIGN(8)
+    {
+        *(.text)
+        *(.text.*)
+        *(.gnu.linkonce.t.*)
+    }
+
+    .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
+    .rel.got  : { *(.rel.got) }
+
+    /* Here starts the second segment, that is copied in RAM and relocated */
+    . = 0x10000000;
+
+    .got      : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
+
+    /* FIXME: If this is put in the other segment, it makes it writable */
+    .dynamic  : { *(.dynamic) }
+
+    /* FIXME: The compiler insists in addressing rodata relative to r9 */
+    .rodata : ALIGN(8)
+    {
+        *(.rodata)
+        *(.rodata.*)
+        *(.gnu.linkonce.r.*)
+    }
+
+    .data : ALIGN(8)
+    {
+        *(.data)
+        *(.data.*)
+        *(.gnu.linkonce.d.*)
+    }
+
+    .bss : ALIGN(8)
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+    }
+
+    /* These are removed since are unused and increase binary size */
+    /DISCARD/ :
+    {
+        *(.interp)
+        *(.dynsym)
+        *(.dynstr)
+        *(.hash)
+        *(.comment)
+        *(.ARM.attributes)
+    }
+}
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/prog3.h b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/prog3.h
new file mode 100644
index 0000000000000000000000000000000000000000..e263fad5b2841783c8b235aa6a87cb3ab712012d
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/prog3.h
@@ -0,0 +1,25 @@
+const unsigned char __attribute__((aligned(8))) testsuite_system_elf[] = {
+  0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x28, 0x00, 0x01, 0x00, 0x00, 0x00,
+  0x99, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x02, 0x00, 0x00, 0x05, 0x34, 0x00, 0x20, 0x00, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
+  0x98, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00,
+  0x22, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+  0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+  0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xcc, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x0c, 0x00, 0x00, 0x10,
+  0x28, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x02, 0xf8,
+  0x00, 0xf0, 0x08, 0xf8, 0x02, 0x48, 0x08, 0xb5, 0x48, 0x44, 0x00, 0xf0,
+  0x05, 0xf8, 0x08, 0xbd, 0x38, 0x00, 0x00, 0x00, 0x02, 0x23, 0x00, 0xdf,
+  0x09, 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, 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, 0x74, 0x65, 0x73, 0x74,
+  0x00, 0x00, 0x00, 0x00
+};
+unsigned int testsuite_system_elf_len = 256;
diff --git a/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/test.txt b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..532c7ab9121d7059d831783b60bd4f3de110a607
--- /dev/null
+++ b/miosix/_tools/testsuite/syscall_testsuite/testsuite_system/test.txt
@@ -0,0 +1,101 @@
+
+testsuite_system.elf:     file format elf32-littlearm
+testsuite_system.elf
+architecture: arm, flags 0x00000050:
+HAS_SYMS, DYNAMIC
+start address 0x00000099
+
+Program Header:
+    LOAD off    0x00000098 vaddr 0x00000098 paddr 0x00000098 align 2**3
+         filesz 0x00000022 memsz 0x00000022 flags r-x
+    LOAD off    0x000000c0 vaddr 0x10000000 paddr 0x10000000 align 2**3
+         filesz 0x00000040 memsz 0x00000040 flags rw-
+ DYNAMIC off    0x000000cc vaddr 0x1000000c paddr 0x1000000c align 2**2
+         filesz 0x00000028 memsz 0x00000028 flags rw-
+
+Dynamic Section:
+  DEBUG                0x00000000
+private flags = 5000002: [Version5 EABI] [has entry point]
+
+Sections:
+Idx Name          Size      VMA       LMA       File off  Algn
+  0 .text         00000022  00000098  00000098  00000098  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, CODE
+  1 .got          0000000c  10000000  10000000  000000c0  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  2 .dynamic      00000028  1000000c  1000000c  000000cc  2**2
+                  CONTENTS, ALLOC, LOAD, DATA
+  3 .rodata       00000008  10000038  10000038  000000f8  2**3
+                  CONTENTS, ALLOC, LOAD, READONLY, DATA
+SYMBOL TABLE:
+00000098 l    d  .text	00000000 .text
+10000000 l    d  .got	00000000 .got
+1000000c l    d  .dynamic	00000000 .dynamic
+10000038 l    d  .rodata	00000000 .rodata
+00000000 l    df *ABS*	00000000 main.c
+1000000c l     O *ABS*	00000000 _DYNAMIC
+10000000 l     O *ABS*	00000000 _GLOBAL_OFFSET_TABLE_
+000000b4 g     F .text	00000000 system
+00000098 g     F .text	00000000 _start
+000000a0 g     F .text	00000010 main
+00000000       F *UND*	00000000 seek
+000000b0 g     F .text	00000000 _exit
+
+
+Contents of section .text:
+ 0098 00f002f8 00f008f8 024808b5 484400f0  .........H..HD..
+ 00a8 05f808bd 38000000 022300df 092300df  ....8....#...#..
+ 00b8 7047                                 pG              
+Contents of section .got:
+ 10000000 0c000010 00000000 00000000           ............    
+Contents of section .dynamic:
+ 1000000c 15000000 00000000 00000000 00000000  ................
+ 1000001c 00000000 00000000 00000000 00000000  ................
+ 1000002c 00000000 00000000                    ........        
+Contents of section .rodata:
+ 10000038 74657374 00000000                    test....        
+
+Disassembly of section .text:
+
+00000098 <_start>:
+_start():
+  98:	f000 f802 	bl	a0 <main>
+  9c:	f000 f808 	bl	b0 <_exit>
+
+000000a0 <main>:
+main():
+  a0:	4802      	ldr	r0, [pc, #8]	; (ac <main+0xc>)
+  a2:	b508      	push	{r3, lr}
+  a4:	4448      	add	r0, r9
+  a6:	f000 f805 	bl	b4 <system>
+  aa:	bd08      	pop	{r3, pc}
+  ac:	00000038 	andeq	r0, r0, r8, lsr r0
+
+000000b0 <_exit>:
+_exit():
+  b0:	2302      	movs	r3, #2
+  b2:	df00      	svc	0
+
+000000b4 <system>:
+system():
+  b4:	2309      	movs	r3, #9
+  b6:	df00      	svc	0
+  b8:	4770      	bx	lr
+
+Disassembly of section .got:
+
+10000000 <.got>:
+10000000:	1000000c 	andne	r0, r0, ip
+	...
+
+Disassembly of section .dynamic:
+
+1000000c <.dynamic>:
+1000000c:	00000015 	andeq	r0, r0, r5, lsl r0
+	...
+
+Disassembly of section .rodata:
+
+10000038 <.rodata>:
+10000038:	74736574 	ldrbtvc	r6, [r3], #-1396	; 0x574
+1000003c:	00000000 	andeq	r0, r0, r0
diff --git a/miosix/_tools/testsuite/testsuite.cpp b/miosix/_tools/testsuite/testsuite.cpp
index bee0f8693748e37c61cab00273b9c365dc242988..1e996d4306501a6186766ec4d5b9dda6c4ccce03 100644
--- a/miosix/_tools/testsuite/testsuite.cpp
+++ b/miosix/_tools/testsuite/testsuite.cpp
@@ -41,6 +41,8 @@
 #include <cassert>
 #include <fcntl.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
+#include <signal.h>
 #include <pthread.h>
 #include <errno.h>
 #include <dirent.h>
@@ -58,6 +60,17 @@
 #include "filesystem/console/console_device.h"
 #include "util/crc16.h"
 
+#ifdef WITH_PROCESSES
+#include "miosix/kernel/elf_program.h"
+#include "miosix/kernel/process.h"
+#include "kernel/process_pool.h"
+#include "kernel/SystemMap.h"
+
+#include "miosix/testsuite/syscall_testsuite/includes.h"
+#include "miosix/testsuite/elf_testsuite/includes.h"
+#include "miosix/testsuite/mpu_testsuite/includes.h"
+#endif //WITH_PROCESSES
+
 using namespace std::tr1;
 using namespace miosix;
 
@@ -115,6 +128,37 @@ static void benchmark_4();
 static void exception_test();
 #endif //__NO_EXCEPTIONS
 
+#ifdef WITH_PROCESSES
+void syscall_test_sleep();
+void process_test_process_ret();
+void syscall_test_system();
+#ifdef WITH_FILESYSTEM
+void syscall_test_files();
+void process_test_file_concurrency();
+void syscall_test_mpu_open();
+void syscall_test_mpu_read();
+void syscall_test_mpu_write();
+#endif //WITH_FILESYSTEM
+
+unsigned int* memAllocation(unsigned int size);
+bool memCheck(unsigned int *base, unsigned int size);
+void runElfTest(const char *name, const unsigned char *filename, unsigned int file_length);
+
+int runProgram(const unsigned char *filename, unsigned int file_length);
+bool isSignaled(int exit_code);
+void mpuTest1();
+void mpuTest2();
+void mpuTest3();
+void mpuTest4();
+void mpuTest5();
+void mpuTest6();
+void mpuTest7();
+void mpuTest8();
+void mpuTest9();
+void mpuTest10();
+#endif //WITH_PROCESSES
+
+
 //main(), calls all tests
 int main()
 {
@@ -123,14 +167,17 @@ int main()
     Thread::setPriority(0);
     for(;;)
     {
-        iprintf("Type 't' for kernel test, 'f' for filesystem test, 'x' for "
-        "exception test, 'b' for benchmarks or 's' for shutdown\n");
+        iprintf("Type:\n 't' for kernel test\n 'f' for filesystem test\n 'x' for "
+        "exception test\n 'b' for benchmarks\n 'p' for process tes\n 'y' for syscall test\n"
+        " 'm' for elf and mpu test\n 's' for shutdown\n");
         char c;
         for(;;)
         {
             c=getchar();
             if(c!='\n') break;
         }
+        //For testing mpu
+        unsigned int *m;
         switch(c)
         {
             case 't':
@@ -202,6 +249,87 @@ int main()
             case 's':
                 iprintf("Shutting down\n");
                 shutdown();
+            case 'y':
+                ledOn();
+                #ifdef WITH_PROCESSES
+                #ifdef WITH_FILESYSTEM
+                syscall_test_files();
+                syscall_test_mpu_open();
+                syscall_test_mpu_read();
+                syscall_test_mpu_write();
+                #else //WITH_FILESYSTEM
+                iprintf("Error, filesystem support is disabled\n");
+                #endif //WITH_FILESYSTEM
+
+                syscall_test_sleep();
+                syscall_test_system();
+                #else //WITH_PROCESSES
+                iprintf("Error, process support is disabled\n");
+                #endif //WITH_PROCESSES
+                ledOff();
+                break;
+            case 'p':
+                #ifdef WITH_PROCESSES
+                ledOn();
+                process_test_process_ret();
+                process_test_file_concurrency();
+                ledOff();
+                #endif //WITH_PROCESSES
+                break;
+            case 'm':
+                //The priority of the test thread must be 1
+                Thread::setPriority(1);
+                ledOn();
+                #ifdef WITH_PROCESSES
+                //Note by TFT: these addresses are only valid for the stm3220g-eval.
+                //FIXME: llok into it
+                // ProcessPool allocates 4096 bytes starting from address 0x64100000
+                // Range : 0x64100000 - 0x64101000
+
+                // First process memory layout
+                // Code region : 0x64101000 - 0x64101400
+                // Data region : 0x64104000 - 0x64108000
+
+                // Second process memory layout
+                // Code region : 0x64101400 - 0x64101800
+                // Data region : 0x64108000 - 0x6410c000
+
+                // Third process memory layout
+                // Code region : 0x64101800 - 0x64101c00
+                // Data region : 0x6410c000 - 0x64110000
+
+                //Altered elfs tests
+                iprintf("\nExecuting ELF tests.\n");
+                iprintf("--------------------\n");
+                runElfTest("Elf Test1", aelf1, aelf1_len);
+                runElfTest("Elf Test2", aelf2, aelf2_len);
+                runElfTest("Elf Test3", aelf3, aelf3_len);
+                runElfTest("Elf Test4", aelf4, aelf4_len);
+                runElfTest("Elf Test5", aelf5, aelf5_len);
+                runElfTest("Elf Test6", aelf6, aelf6_len);
+                runElfTest("Elf Test7", aelf7, aelf7_len);
+
+                //Mpu tests
+                iprintf("\n\nExecuting MPU tests.\n");
+                iprintf("---------------------\n");
+                m = memAllocation(4096);
+                mpuTest1();
+                mpuTest2();
+                mpuTest3();
+                mpuTest4();
+                mpuTest5();
+                mpuTest6();
+                mpuTest7();
+                mpuTest8();
+                mpuTest9();
+                mpuTest10();
+                ProcessPool::instance().deallocate(m);
+                #else //#ifdef WITH_PROCESSES
+                iprintf("Error, process support is disabled\n");
+                #endif //#ifdef WITH_PROCESSES
+                ledOff();
+                Thread::setPriority(0);
+            break;
             default:
                 iprintf("Unrecognized option\n");
         }
@@ -240,6 +368,212 @@ static void fail(const char *cause)
     reboot();
 }
 
+#ifdef WITH_PROCESSES
+
+void process_test_file_concurrency()
+{
+    test_name("Process file concurrency");
+
+    remove("/file1.bin");
+    remove("/file2.bin");
+
+    ElfProgram prog1(reinterpret_cast<const unsigned int*>(testsuite_file1_elf), testsuite_file1_elf_len);
+    ElfProgram prog2(reinterpret_cast<const unsigned int*>(testsuite_file2_elf), testsuite_file2_elf_len);
+
+    pid_t p1 = Process::create(prog1);
+    pid_t p2 = Process::create(prog2);
+
+    int res1 = 0, res2 = 0;
+
+    Process::waitpid(p1, &res1, 0);
+    Process::waitpid(p2, &res2, 0);
+
+    FILE *f1 = fopen("/file1.bin", "rb");
+    FILE *f2 = fopen("/file2.bin", "rb");
+
+    if(!f1) fail("Unable to open first file");
+    if(!f2) fail("Unable to open second file");
+
+    char buffer[10];
+
+    for(int i = 0; i < 1000; i++)
+    {
+        fread(buffer, 1, 9, f1);
+        if(strncmp(buffer, "file1.bin", 9) != 0) fail("Wrong data from file 1");
+    }
+
+    for(int i = 0; i < 1000; i++)
+    {
+        fread(buffer, 1, 9, f2);
+        if(strncmp(buffer, "file2.bin", 9) != 0) fail("Wrong data from file 2");
+    }
+
+    fclose(f1);
+    fclose(f2);
+
+    pass();
+}
+
+void process_test_process_ret()
+{
+    test_name("Process return value");
+    ElfProgram prog(reinterpret_cast<const unsigned int*>(testsuite_simple_elf),testsuite_simple_elf_len);
+    int ret = 0;
+    pid_t p = Process::create(prog);
+    Process::waitpid(p, &ret, 0);
+    //iprintf("Returned value is %d\n", WEXITSTATUS(ret));
+    if(WEXITSTATUS(ret) != 42) fail("Wrong returned value");
+    pass();
+}
+
+void syscall_test_mpu_open()
+{
+    test_name("open and MPU");
+    ElfProgram prog(reinterpret_cast<const unsigned int*>(testsuite_syscall_mpu_open_elf), testsuite_syscall_mpu_open_elf_len);
+    int ret = 0;
+    pid_t p = Process::create(prog);
+    Process::waitpid(p, &ret, 0);
+    //iprintf("Returned value is %d\n", ret);
+    if(WTERMSIG(ret) != SIGSYS) fail("0x00000000 is not a valid address!");
+    pass();
+}
+
+void syscall_test_mpu_read()
+{
+    test_name("read calls and MPU");
+    ElfProgram prog(reinterpret_cast<const unsigned int*>(testsuite_syscall_mpu_read_elf), testsuite_syscall_mpu_read_elf_len);
+    int ret = 0;
+    pid_t p = Process::create(prog);
+    Process::waitpid(p, &ret, 0);
+    //iprintf("Returned value is %d\n", ret);
+    if(WTERMSIG(ret) != SIGSYS) fail("0x00000000 is not a valid address!");
+    pass();
+}
+
+void syscall_test_mpu_write()
+{
+    test_name("write and MPU");
+    ElfProgram prog(reinterpret_cast<const unsigned int*>(testsuite_syscall_mpu_write_elf), testsuite_syscall_mpu_write_elf_len);
+    int ret = 0;
+    pid_t p = Process::create(prog);
+    Process::waitpid(p, &ret, 0);
+    iprintf("Returned value is %d\n", ret);
+    if(WTERMSIG(ret) != SIGSYS) fail("0x00000000 is not a valid address!");
+    pass();
+}
+
+void syscall_test_system()
+{
+    test_name("system");
+	if(SystemMap::instance().getElfCount() != 0)
+		fail("The system lookup table should be empty");
+	else
+		iprintf("The system lookup table is empty. Correct.\n");
+	
+	SystemMap::instance().addElfProgram("test", reinterpret_cast<const unsigned int*>(testsuite_simple_elf), testsuite_simple_elf_len);
+	
+	if(SystemMap::instance().getElfCount() != 1)
+		fail("Now the system lookup table should contain 1 program");
+	else
+		iprintf("The system lookup table contain one program. Correct.\n");
+	
+	std::pair<const unsigned int*, unsigned int> sysret = SystemMap::instance().getElfProgram("test");
+	
+	if(sysret.first == 0 || sysret.second == 0)
+		fail("The system lookup table has returned an invalid process size or an invalid elf pointer for the process");
+	
+	ElfProgram prog(reinterpret_cast<const unsigned int*>(testsuite_system_elf), testsuite_system_elf_len);
+	
+	int ret = 0;
+	pid_t p = Process::create(prog);
+	Process::waitpid(p, &ret, 0);
+	
+	if(WEXITSTATUS(ret) != 42){
+		iprintf("Host process returned: %d\n", WEXITSTATUS(ret));
+		fail("The system inside a process has failed");
+	}
+
+	SystemMap::instance().removeElfProgram("test");
+	
+	if(SystemMap::instance().getElfCount() != 0)
+		fail("The system lookup table now should be empty.\n");
+	
+	pass();
+}
+
+void syscall_test_sleep(){
+	test_name("System Call: sleep");
+	ElfProgram prog(reinterpret_cast<const unsigned int*>(testsuite_sleep_elf),testsuite_sleep_elf_len);
+	
+//	iprintf("diff was: %d\n", (unsigned int)getTick());
+	
+	int ret = 0;
+	long long time = getTick();
+	pid_t p = Process::create(prog);
+	Process::waitpid(p, &ret, 0);
+	
+	long long diff = llabs((getTick() - time));
+	
+	if (llabs(diff - 5*TICK_FREQ) > static_cast<long long>(TICK_FREQ * 0.02))
+		fail("The sleep should have only a little more than 5 seconds.");
+	
+	pass();
+}
+
+void syscall_test_files(){
+	test_name("System Call: open, read, write, seek, close, system");
+	
+	ElfProgram prog(reinterpret_cast<const unsigned int*>(testsuite_syscall_elf),testsuite_syscall_elf_len);
+	int ret = 0;
+	
+	remove("/foo.bin");
+	
+	pid_t child = Process::create(prog);
+	Process::waitpid(child, &ret, 0);
+	
+	iprintf("Returned value %d\n", WEXITSTATUS(ret));
+	switch(WEXITSTATUS(ret)){
+		case 0:
+			pass();
+			break;
+		case 1:
+			fail("Open with O_RDWR should have failed, the file doesn't exist");
+			break;
+		case 2:
+			fail("Cannot craete new file");
+			break;
+		case 3:
+			fail("file descriptor not valid");
+			break;
+		case 4:
+			fail("write has written the wrong amount of data");
+			break;
+		case 5:
+			fail("read has read the wrong amount of data");
+			break;
+		case 6:
+			fail("readed data doesn't match the written one");
+			break;
+		case 7:
+			fail("close hasn't returned 0");
+			break;
+		case 8:
+			fail("open with O_RDWR failed, but the file exists");
+			break;
+		case 9:
+			fail("read has return the wrogn amount of data");
+			break;
+		case 10:
+			fail("readed data doesn't match the written one");
+			break;
+		case 11:
+			fail("close hasn't returned 0");
+			break;
+	}
+}
+
+#endif //WITH_PROCESSES
+
 //
 // Test 1
 //
@@ -4258,3 +4592,279 @@ static void benchmark_4()
     }
     iprintf("%d fast disable/enable interrupts pairs per second\n",i);
 }
+
+#ifdef WITH_PROCESSES
+
+unsigned int* memAllocation(unsigned int size)
+{
+	unsigned int *p = ProcessPool::instance().allocate(size);
+	memset(p, WATERMARK_FILL, size);
+	iprintf("Allocated %d bytes. Base: %p. Size: 0x%x.\n\n", size, p, size);
+	return p;
+}
+
+// Returns true if a watermark filled memory zone is not corrupted.
+// 'base' must be 4-byte aligned
+bool memCheck(unsigned int *base, unsigned int size)
+{
+	for(unsigned int i = 0; i < size / 4; i++)
+	{
+		if(*(base + i) != WATERMARK_FILL)
+			return false;
+	}
+	return true;
+}
+
+void runElfTest(const char *name, const unsigned char *filename, unsigned int file_length)
+{
+	iprintf("Executing %s...", name);
+	try
+	{
+		ElfProgram prog(reinterpret_cast<const unsigned int*>(filename),file_length);
+		iprintf("not passed.\n");
+	}
+	catch (std::runtime_error &err)
+	{
+		iprintf("passed.\n");
+	}
+}
+
+//It runs the program, waits for its exit, and returns the exit code
+int runProgram(const unsigned char *filename, unsigned int file_length)
+{
+	int ec;
+	ElfProgram prog(reinterpret_cast<const unsigned int*>(filename), file_length);
+	pid_t child=Process::create(prog);
+	Process::waitpid(child, &ec, 0);
+	return ec;
+}
+
+//Returns true if the process has been signaled with SIGSEV
+bool isSignaled(int exit_code)
+{
+	if(WIFSIGNALED(exit_code) && WTERMSIG(exit_code)==SIGSEGV)
+	{
+		return true;
+	}
+	return false;
+}
+
+void mpuTest1()
+{
+	int ec;
+	unsigned int *addr = (unsigned int*) 0x64100000;
+	iprintf("Executing MPU Test 1...\n");
+	ec = runProgram(test1_elf, test1_elf_len);
+	if(isSignaled(ec))
+	{
+		if(*addr == 0xbbbbbbbb)
+			iprintf("...not passed! The process has written a forbidden memory location.\n\n");
+		else if(*addr == WATERMARK_FILL)
+			iprintf("...passed!\n\n");
+		else
+			iprintf("...not passed! Memory has been somehow corrupted.\n\n");
+	}
+	else
+	{
+		iprintf("...not passed! Process exited normally.\n\n");
+	}
+}
+
+void mpuTest2()
+{
+	int ec;
+	unsigned int *addr = (unsigned int*) 0x64100200;
+	iprintf("Executing MPU Test 2...\n");
+	ec = runProgram(test2_elf, test2_elf_len);
+	if(isSignaled(ec))
+	{
+		if(*addr == WATERMARK_FILL)
+			iprintf("...passed!\n\n");
+		else
+			iprintf("...not passed! Memory has been somehow corrupted.\n\n");
+	}
+	else
+	{
+		iprintf("...not passed! Process exited normally.\n\n");
+	}
+}
+
+void mpuTest3()
+{
+	int ec;
+	unsigned int *addr = (unsigned int*) 0x64100200;
+	iprintf("Executing MPU Test 3...\n");
+	ec = runProgram(test3_elf, test3_elf_len);
+	if(isSignaled(ec))
+	{
+		if(*addr == 0xbbbbbbbb)
+			iprintf("...not passed! The process has written a forbidden memory location.\n\n");
+		else
+			iprintf("...passed!\n\n");
+	}
+	else
+	{
+		iprintf("...not passed! Process exited normally.\n\n");
+	}
+}
+
+void mpuTest4()
+{
+	int ec;
+	iprintf("Executing MPU Test 4...\n");
+	ec = runProgram(test4_elf, test4_elf_len);
+	if(isSignaled(ec))
+	{
+		iprintf("...passed!.\n\n");
+	}
+	else
+	{
+		iprintf("...not passed! Process exited normally.\n\n");
+	}
+}
+
+void mpuTest5()
+{
+	int ec;
+	unsigned int *addr = (unsigned int*) 0x64101000;
+	iprintf("Executing MPU Test 5...\n");
+	ec = runProgram(test5_elf, test5_elf_len);
+	if(isSignaled(ec))
+	{
+		if(*addr == 0xbbbbbbbb)
+			iprintf("...not passed! The process has written a forbidden memory location.\n\n");
+		else
+			iprintf("...passed!.\n\n");
+	}
+	else
+	{
+		iprintf("...not passed! Process exited normally.\n\n");
+	}
+}
+
+void mpuTest6()
+{
+	int ec;
+	unsigned int *addr = (unsigned int*) 0x64101404;
+	iprintf("Executing MPU Test 6...\n");
+	ec = runProgram(test6_elf, test6_elf_len);
+	if(isSignaled(ec))
+	{
+		if(*addr == 0xbbbbbbbb)
+			iprintf("...not passed! The process has written a forbidden memory location.\n\n");
+		else
+			iprintf("...passed!.\n\n");
+	}
+	else
+	{
+		iprintf("...not passed! Process exited normally.\n\n");
+	}
+}
+
+void mpuTest7()
+{
+	int ec;
+        unsigned int memSize = 8192;
+        
+        iprintf("Executing MPU Test 7...\n");
+        unsigned int *p = ProcessPool::instance().allocate(memSize);
+        memset(p, WATERMARK_FILL, memSize);
+	ElfProgram prog(reinterpret_cast<const unsigned int*>(test7_elf), test7_elf_len);
+	pid_t child=Process::create(prog);
+	delayMs(1000);
+	Process::waitpid(child, &ec, 0);
+	if(isSignaled(ec))
+	{       
+                if(memCheck(p, memSize) == true)
+                    iprintf("...passed!.\n\n");
+                else
+                    iprintf("...not passed! Memory NOT sane!");
+                ProcessPool::instance().deallocate(p);
+	}
+	else
+	{
+		iprintf("...not passed! Process exited normally.\n\n");
+                ProcessPool::instance().deallocate(p);
+	}
+}
+
+void mpuTest8()
+{
+	// We create two processes. The first goes to sleep for 2 seconds,
+	// while the second process tries to access the data region of the
+	// first.
+	unsigned int *addr = (unsigned int*) 0x64104004;
+	iprintf("Executing MPU Test 8...\n");
+	ElfProgram prog1(reinterpret_cast<const unsigned int*>(test8_1_elf),test8_1_elf_len);
+	ElfProgram prog2(reinterpret_cast<const unsigned int*>(test8_2_elf),test8_2_elf_len);
+	pid_t child1=Process::create(prog1);
+	pid_t child2=Process::create(prog2);
+	int ec1, ec2;
+	Process::waitpid(child1,&ec1,0);
+	Process::waitpid(child2,&ec2,0);
+	if(WIFSIGNALED(ec2) && (WTERMSIG(ec2) == SIGSEGV) && WIFEXITED(ec1))
+	{
+		if(*addr == 0xbbbbbbbb)
+			iprintf("...not passed! The process has written a forbidden memory location.\n\n");
+		else
+			iprintf("...passed!.\n\n");
+	}
+	else
+	{
+		iprintf("...not passed!\n\n");
+	}
+}
+
+void mpuTest9()
+{
+	iprintf("Executing MPU Test 9...\n");
+	ElfProgram prog(reinterpret_cast<const unsigned int*>(test9_elf),test9_elf_len);
+	std::vector<pid_t> pids;
+	int ec;
+	for(unsigned int i = 0; i < 100; i++)
+	{
+		pid_t pid;
+		try {
+			pid = Process::create(prog);
+			pids.push_back(pid);
+		}
+		catch (std::bad_alloc &ex)
+		{
+			iprintf("Bad alloc raised: %s\nIteration is: %d\n", ex.what(), i);
+			break;
+		}
+	}
+	iprintf("Allocated %d processes before system ran out of memory.\n", pids.size());
+	for(unsigned int i = 0; i < pids.size(); i++)
+	{
+		Process::waitpid(pids[i], &ec, 0);
+		//iprintf("Process %d has terminated with return code: %d\n", pids[i], ec);
+	}
+	iprintf("...passed!.\n\n");
+}
+
+void mpuTest10()
+{
+	// The first process is allocated and sent to sleep. The second process statically
+	// allocates a big array and calls a syscall, which will try to write in the memory
+	// chunk owned by the first process.
+	// The first process should end properly, the second process should fault.
+	int ec1, ec2;
+	iprintf("Executing MPU Test 10...\n");
+	ElfProgram prog1(reinterpret_cast<const unsigned int*>(test10_1_elf), test10_1_elf_len);
+	ElfProgram prog2(reinterpret_cast<const unsigned int*>(test10_2_elf), test10_2_elf_len);
+	pid_t child1=Process::create(prog1);
+	pid_t child2=Process::create(prog2);
+	Process::waitpid(child1, &ec1, 0);
+	Process::waitpid(child2, &ec2, 0);
+
+	if(!isSignaled(ec1) && isSignaled(ec2))
+	{
+		iprintf("...passed!.\n\n");
+	}
+	else
+	{
+		iprintf("...not passed!\n\n");
+	}
+}
+#endif //WITH_PROCESSES
diff --git a/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/interfaces-impl/portability.cpp b/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/interfaces-impl/portability.cpp
index 23894c03b497d5df22b108d2b0bfce451737f4a2..dac606dfc76d34c788e8408338c27d2777e79352 100644
--- a/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/interfaces-impl/portability.cpp
+++ b/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/interfaces-impl/portability.cpp
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2008, 2009, 2010 by Terraneo Federico                   *
+ *   Copyright (C) 2008, 2009, 2010, 2011, 2012 by Terraneo Federico       *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -189,6 +189,33 @@ void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp,
     ctxsave[16]=0x1f;//thread starts in system mode with irq and fiq enabled.
 }
 
+#ifdef WITH_PROCESSES
+
+void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp,
+            void *argv, unsigned int *gotBase)
+{
+    ctxsave[0]=(unsigned int)argv;
+    ctxsave[1]=0;
+    ctxsave[2]=0;
+    ctxsave[3]=0;
+    ctxsave[4]=0;
+    ctxsave[5]=0;
+    ctxsave[6]=0;
+    ctxsave[7]=0;
+    ctxsave[8]=0;
+    ctxsave[9]=(unsigned int)gotBase;
+    ctxsave[10]=0;
+    ctxsave[11]=0;
+    ctxsave[12]=0;
+    ctxsave[13]=(unsigned int)sp;//Initialize the thread's stack pointer
+    ctxsave[14]=0xffffffff;//threadLauncher never returns, so lr is not important
+    //Initialize the thread's program counter to the beginning of the entry point
+    ctxsave[15]=(unsigned int)pc;
+    ctxsave[16]=0x1f;//thread starts in system mode with irq and fiq enabled.
+}
+
+#endif //WITH_PROCESSES
+
 void IRQportableStartKernel()
 {
     PCONP|=(1<<1);//Enable TIMER0
diff --git a/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/interfaces-impl/portability_impl.h b/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/interfaces-impl/portability_impl.h
index 0cb8accadea242a76a3fb5c8a4cb0c2015f432b6..8da834c8e7f7cd2683a456e80b810fe7f2a060eb 100644
--- a/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/interfaces-impl/portability_impl.h
+++ b/miosix/arch/arm7_lpc2000/lpc2138_miosix_board/interfaces-impl/portability_impl.h
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2008, 2009, 2010 by Terraneo Federico                   *
+ *   Copyright (C) 2008, 2009, 2010, 2011, 2012 by Terraneo Federico       *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -181,7 +181,9 @@ namespace miosix_private {
 
 inline void doYield()
 {
-    asm volatile("swi 0");
+    asm volatile("movs  r3, #0\n\t"
+                 "swi   0"
+                 :::"r3");
 }
 
 inline void doDisableInterrupts()
diff --git a/miosix/arch/cortexM3_stm32/common/interfaces-impl/portability.cpp b/miosix/arch/cortexM3_stm32/common/interfaces-impl/portability.cpp
index 93406ec7be268f319354ff00548622da5e7502c3..aad6f88cd81757f0ff750364e3f1aa66840e0724 100644
--- a/miosix/arch/cortexM3_stm32/common/interfaces-impl/portability.cpp
+++ b/miosix/arch/cortexM3_stm32/common/interfaces-impl/portability.cpp
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2010 by Terraneo Federico                               *
+ *   Copyright (C) 2010, 2011, 2012 by Terraneo Federico                   *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -168,6 +168,29 @@ void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp,
     //leaving the content of r4-r11 uninitialized
 }
 
+#ifdef WITH_PROCESSES
+
+void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp,
+        void *argv, unsigned int *gotBase)
+{
+    unsigned int *stackPtr=sp;
+    stackPtr--; //Stack is full descending, so decrement first
+    *stackPtr=0x01000000; stackPtr--;                                 //--> xPSR
+    *stackPtr=reinterpret_cast<unsigned long>(pc); stackPtr--;        //--> pc
+    *stackPtr=0xffffffff; stackPtr--;                                 //--> lr
+    *stackPtr=0; stackPtr--;                                          //--> r12
+    *stackPtr=0; stackPtr--;                                          //--> r3
+    *stackPtr=0; stackPtr--;                                          //--> r2
+    *stackPtr=0; stackPtr--;                                          //--> r1
+    *stackPtr=reinterpret_cast<unsigned long >(argv);                 //--> r0
+
+    ctxsave[0]=reinterpret_cast<unsigned long>(stackPtr);             //--> psp
+    ctxsave[6]=reinterpret_cast<unsigned long>(gotBase);              //--> r9 
+    //leaving the content of r4-r8,r10-r11 uninitialized
+}
+
+#endif //WITH_PROCESSES
+
 void IRQportableStartKernel()
 {
     //Enable fault handlers
diff --git a/miosix/arch/cortexM3_stm32/common/interfaces-impl/portability_impl.h b/miosix/arch/cortexM3_stm32/common/interfaces-impl/portability_impl.h
index c6686a632e24ecbad9eeab1f91bcf7a2b6216e23..e40061aa5df985f07b8f1e316cc554d79f25f1cb 100644
--- a/miosix/arch/cortexM3_stm32/common/interfaces-impl/portability_impl.h
+++ b/miosix/arch/cortexM3_stm32/common/interfaces-impl/portability_impl.h
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2010 by Terraneo Federico                               *
+ *   Copyright (C) 2010, 2011, 2012 by Terraneo Federico                   *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -102,7 +102,9 @@ namespace miosix_private {
 
 inline void doYield()
 {
-    asm volatile("svc 0");
+    asm volatile("movs r3, #0\n\t"
+                 "svc  0"
+                 :::"r3");
 }
 
 inline void doDisableInterrupts()
diff --git a/miosix/arch/cortexM3_stm32f2/common/core/interrupts.cpp b/miosix/arch/cortexM3_stm32f2/common/core/interrupts.cpp
index 411cbda4887cd546744aede791391c37e5e28403..40eb7a1b5192f4b8085c2e3d358c3d17abc32311 100644
--- a/miosix/arch/cortexM3_stm32f2/common/core/interrupts.cpp
+++ b/miosix/arch/cortexM3_stm32f2/common/core/interrupts.cpp
@@ -26,6 +26,7 @@
  ***************************************************************************/
 
 #include "kernel/logging.h"
+#include "kernel/kernel.h"
 #include "config/miosix_settings.h"
 #include "interfaces/portability.h"
 #include "interfaces/arch_registers.h"
@@ -54,34 +55,46 @@ static void printUnsignedInt(unsigned int x)
     IRQerrorLog(result);
 }
 
+#endif //WITH_ERRLOG
+
 /**
  * \internal
- * Print the program counter of the thread that was running when the exception
+ * \return the program counter of the thread that was running when the exception
  * occurred.
  */
-static void printProgramCounter()
+static unsigned int getProgramCounter()
 {
-    register unsigned int pc;
+    register unsigned int result;
     // Get program counter when the exception was thrown from stack frame
     asm volatile("mrs   %0,  psp    \n\t"
                  "add   %0, %0, #24 \n\t"
-                 "ldr   %0, [%0]    \n\t":"=r"(pc));
-    printUnsignedInt(pc);
+                 "ldr   %0, [%0]    \n\t":"=r"(result));
+    return result;
 }
 
-#endif //WITH_ERRLOG
-
 void NMI_Handler()
 {
     IRQerrorLog("\r\n***Unexpected NMI\r\n");
     miosix_private::IRQsystemReboot();
 }
 
-void HardFault_Handler()
+void __attribute__((naked)) HardFault_Handler()
 {
+    saveContext();
+    //Call HardFault_impl(). Name is a C++ mangled name.
+    asm volatile("bl _Z14HardFault_implv");
+    restoreContext();
+}
+
+void __attribute__((noinline)) HardFault_impl()
+{
+    #ifdef WITH_PROCESSES
+    if(miosix::Thread::IRQreportFault(miosix_private::FaultData(
+        HARDFAULT,getProgramCounter()))) return;
+    #endif //WITH_PROCESSES
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected HardFault @ ");
-    printProgramCounter();
+    printUnsignedInt(getProgramCounter());
     unsigned int hfsr=SCB->HFSR;
     if(hfsr & SCB_HFSR_FORCED_Msk)
         IRQerrorLog("Fault escalation occurred\r\n");
@@ -91,12 +104,32 @@ void HardFault_Handler()
     miosix_private::IRQsystemReboot();
 }
 
-void MemManage_Handler()
+void __attribute__((naked)) MemManage_Handler()
 {
+    saveContext();
+    //Call MemManage_impl(). Name is a C++ mangled name.
+    asm volatile("bl _Z14MemManage_implv");
+    restoreContext();
+}
+
+void __attribute__((noinline)) MemManage_impl()
+{
+    unsigned int cfsr=SCB->CFSR;
+    #ifdef WITH_PROCESSES
+    int id, arg=0;
+    if(cfsr & 0x00000001) id=MP_XN;
+    else if(cfsr & 0x00000080) { id=MP; arg=SCB->MMFAR; }
+    else id=MP_NOADDR;
+    if(miosix::Thread::IRQreportFault(miosix_private::FaultData(
+        id,getProgramCounter(),arg)))
+    {
+        SCB->SHCSR &= ~(1<<13); //Clear MEMFAULTPENDED bit
+        return;
+    }
+    #endif //WITH_PROCESSES
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected MemManage @ ");
-    printProgramCounter();
-    unsigned int cfsr=SCB->CFSR;
+    printUnsignedInt(getProgramCounter());
     if(cfsr & 0x00000080)
     {
         IRQerrorLog("Fault caused by attempted access to ");
@@ -118,7 +151,7 @@ void BusFault_Handler()
 {
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected BusFault @ ");
-    printProgramCounter();
+    printUnsignedInt(getProgramCounter());
     unsigned int cfsr=SCB->CFSR;
     if(cfsr & 0x00008000)
     {
@@ -139,12 +172,36 @@ void BusFault_Handler()
     miosix_private::IRQsystemReboot();
 }
 
-void UsageFault_Handler()
+void __attribute__((naked)) UsageFault_Handler()
+{
+    saveContext();
+    //Call UsageFault_impl(). Name is a C++ mangled name.
+    asm volatile("bl _Z15UsageFault_implv");
+    restoreContext();
+}
+
+void __attribute__((noinline)) UsageFault_impl()
 {
+    unsigned int cfsr=SCB->CFSR;
+    #ifdef WITH_PROCESSES
+    int id;
+    if(cfsr & 0x02000000) id=UF_DIVZERO;
+    else if(cfsr & 0x01000000) id=UF_UNALIGNED;
+    else if(cfsr & 0x00080000) id=UF_COPROC;
+    else if(cfsr & 0x00040000) id=UF_EXCRET;
+    else if(cfsr & 0x00020000) id=UF_EPSR;
+    else if(cfsr & 0x00010000) id=UF_UNDEF;
+    else id=UF_UNEXP;
+    if(miosix::Thread::IRQreportFault(miosix_private::FaultData(
+        id,getProgramCounter())))
+    {
+        SCB->SHCSR &= ~(1<<12); //Clear USGFAULTPENDED bit
+        return;
+    }
+    #endif //WITH_PROCESSES
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected UsageFault @ ");
-    printProgramCounter();
-    unsigned int cfsr=SCB->CFSR;
+    printUnsignedInt(getProgramCounter());
     if(cfsr & 0x02000000) IRQerrorLog("Divide by zero\r\n");
     if(cfsr & 0x01000000) IRQerrorLog("Unaligned memory access\r\n");
     if(cfsr & 0x00080000) IRQerrorLog("Attempted coprocessor access\r\n");
@@ -159,7 +216,7 @@ void DebugMon_Handler()
 {
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected DebugMon @ ");
-    printProgramCounter();
+    printUnsignedInt(getProgramCounter());
     #endif //WITH_ERRLOG
     miosix_private::IRQsystemReboot();
 }
@@ -168,7 +225,7 @@ void PendSV_Handler()
 {
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected PendSV @ ");
-    printProgramCounter();
+    printUnsignedInt(getProgramCounter());
     #endif //WITH_ERRLOG
     miosix_private::IRQsystemReboot();
 }
diff --git a/miosix/arch/cortexM3_stm32f2/common/core/interrupts.h b/miosix/arch/cortexM3_stm32f2/common/core/interrupts.h
index 6b74a54ff907127a2719b87ddcae0e6b5a782fb7..cdb648f554046e8a59c519aa79826e1bf6f03620 100644
--- a/miosix/arch/cortexM3_stm32f2/common/core/interrupts.h
+++ b/miosix/arch/cortexM3_stm32f2/common/core/interrupts.h
@@ -34,4 +34,23 @@
  */
 void unexpectedInterrupt();
 
+/**
+ * Possible kind of faults that the Cortex-M3 can report.
+ * They are used to print debug information if a process causes a fault
+ */
+enum FaultType
+{
+    MP=1,          //Process attempted data access outside its memory
+    MP_NOADDR=2,   //Process attempted data access outside its memory (missing addr)
+    MP_XN=3,       //Process attempted code access outside its memory
+    UF_DIVZERO=4,  //Process attempted to divide by zero
+    UF_UNALIGNED=5,//Process attempted unaligned memory access
+    UF_COPROC=6,   //Process attempted a coprocessor access
+    UF_EXCRET=7,   //Process attempted an exception return
+    UF_EPSR=8,     //Process attempted to access the EPSR
+    UF_UNDEF=9,    //Process attempted to execute an invalid instruction
+    UF_UNEXP=10,   //Unexpected usage fault
+    HARDFAULT=11   //Hardfault (for example process executed a BKPT instruction)
+};
+
 #endif	//INTERRUPTS_H
diff --git a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/disk.cpp b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/disk.cpp
index f1108d490bd9eea5a6859693db5af62a2ff4114d..a0f6e5f7329234b6648877aa36b49836d99b1ae8 100644
--- a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/disk.cpp
+++ b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/disk.cpp
@@ -140,9 +140,11 @@ static CardType cardType=Invalid;
 
 //SD card GPIOs
 typedef Gpio<GPIOC_BASE,8>  sdD0;
-typedef Gpio<GPIOC_BASE,9>  sdD1;
+#ifndef _BOARD_STM3220G_EVAL //QUIRK: serial port and SD have pins in common
+typedef Gpio<GPIOC_BASE,9>  sdD1; 
 typedef Gpio<GPIOC_BASE,10> sdD2;
 typedef Gpio<GPIOC_BASE,11> sdD3;
+#endif //_BOARD_STM3220G_EVAL
 typedef Gpio<GPIOC_BASE,12> sdCLK;
 typedef Gpio<GPIOD_BASE,2>  sdCMD;
 
diff --git a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp
index e5d69aeb4768b302804917e970d3e35903c8e486..f0f1d1f314ce14054c6534377124982e52c0d749 100644
--- a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp
+++ b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability.cpp
@@ -32,7 +32,11 @@
 #include "interfaces/bsp.h"
 #include "kernel/scheduler/scheduler.h"
 #include "kernel/scheduler/tick_interrupt.h"
+#include "core/interrupts.h"
 #include <algorithm>
+#include <cstdio>
+#include <cstring>
+#include <cassert>
 
 /**
  * \internal
@@ -98,7 +102,7 @@ void ISR_preempt() __attribute__((noinline));
 void ISR_preempt()
 {
     IRQstackOverflowCheck();
-    miosix::IRQtickInterrupt();
+    miosix::IRQtickInterrupt();  
 }
 
 /**
@@ -111,8 +115,48 @@ void ISR_preempt()
 void ISR_yield() __attribute__((noinline));
 void ISR_yield()
 {
+    #ifdef WITH_PROCESSES
+    // WARNING: Temporary fix. Rationale:
+    // This fix is intended to avoid kernel or process faulting due to
+    // another process actions. Consider the case in which a process statically
+    // allocates a big array such that there is no space left for saving
+    // context data. If the process issues a system call, in the following
+    // interrupt the context is saved, but since there is no memory available
+    // for all the context data, a mem manage interrupt is set to 'pending'. Then,
+    // a fake syscall is issued, based on the value read on the stack (which
+    // the process hasn't set due to the memory fault and is likely to be 0);
+    // this syscall is usually a yield (due to the value of 0 above),
+    // which can cause the scheduling of the kernel thread. At this point,
+    // the pending mem fault is issued from the kernel thread, causing the
+    //kernel fault and reboot. This is caused by the mem fault interrupt
+    // having less priority of the other interrupts.
+    // This fix checks if there is a mem fault interrupt pending, and, if so,
+    // it clears it and returns before calling the previously mentioned fake
+    // syscall.
+    if(SCB->SHCSR & (1<<13))
+    {
+        if(miosix::Thread::IRQreportFault(miosix_private::FaultData(
+            MP,0,0)))
+        {
+            SCB->SHCSR &= ~(1<<13); //Clear MEMFAULTPENDED bit
+            return;
+        }
+    }
+    #endif // WITH_PROCESSES
     IRQstackOverflowCheck();
+    
+    #ifdef WITH_PROCESSES
+    //If processes are enabled, check the content of r3. If zero then it
+    //it is a simple yield, otherwise handle the syscall
+    //Note that it is required to use ctxsave and not cur->ctxsave because
+    //at this time we do not know if the active context is user or kernel
+    unsigned int threadSp=ctxsave[0];
+    unsigned int *processStack=reinterpret_cast<unsigned int*>(threadSp);
+    if(processStack[3]!=0) miosix::Thread::IRQhandleSvc(processStack[3]);
+    else miosix::Scheduler::IRQfindNextThread();
+    #else //WITH_PROCESSES
     miosix::Scheduler::IRQfindNextThread();
+    #endif //WITH_PROCESSES
 }
 
 #ifdef SCHED_TYPE_CONTROL_BASED
@@ -168,6 +212,150 @@ void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp,
     //leaving the content of r4-r11 uninitialized
 }
 
+#ifdef WITH_PROCESSES
+
+//
+// class FaultData
+//
+
+void FaultData::print() const
+{
+    switch(id)
+    {
+        case MP:
+            iprintf("* Attempted data access @ 0x%x (PC was 0x%x)\n",arg,pc);
+            break;
+        case MP_NOADDR:
+            iprintf("* Invalid data access (PC was 0x%x)\n",pc);
+            break;
+        case MP_XN:
+            iprintf("* Attempted instruction fetch @ 0x%x\n",pc);
+            break;
+        case UF_DIVZERO:
+            iprintf("* Dvide by zero (PC was 0x%x)\n",pc);
+            break;
+        case UF_UNALIGNED:
+            iprintf("* Unaligned memory access (PC was 0x%x)\n",pc);
+            break;
+        case UF_COPROC:
+            iprintf("* Attempted coprocessor access (PC was 0x%x)\n",pc);
+            break;
+        case UF_EXCRET:
+            iprintf("* Invalid exception return sequence (PC was 0x%x)\n",pc);
+            break;
+        case UF_EPSR:
+            iprintf("* Attempted access to the EPSR (PC was 0x%x)\n",pc);
+            break;
+        case UF_UNDEF:
+            iprintf("* Undefined instruction (PC was 0x%x)\n",pc);
+            break;
+        case UF_UNEXP:
+            iprintf("* Unexpected usage fault (PC was 0x%x)\n",pc);
+            break;
+        case HARDFAULT:
+            iprintf("* Hardfault (PC was 0x%x)\n",pc);
+            break;
+    }
+}
+
+void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp,
+        void *argv, unsigned int *gotBase)
+{
+    unsigned int *stackPtr=sp;
+    stackPtr--; //Stack is full descending, so decrement first
+    *stackPtr=0x01000000; stackPtr--;                                 //--> xPSR
+    *stackPtr=reinterpret_cast<unsigned long>(pc); stackPtr--;        //--> pc
+    *stackPtr=0xffffffff; stackPtr--;                                 //--> lr
+    *stackPtr=0; stackPtr--;                                          //--> r12
+    *stackPtr=0; stackPtr--;                                          //--> r3
+    *stackPtr=0; stackPtr--;                                          //--> r2
+    *stackPtr=0; stackPtr--;                                          //--> r1
+    *stackPtr=reinterpret_cast<unsigned long >(argv);                 //--> r0
+
+    ctxsave[0]=reinterpret_cast<unsigned long>(stackPtr);             //--> psp
+    ctxsave[6]=reinterpret_cast<unsigned long>(gotBase);              //--> r9                                               //--> r9
+    //leaving the content of r4-r8,r10-r11 uninitialized
+}
+
+static unsigned int sizeToMpu(unsigned int size)
+{
+    assert(size>=32);
+    unsigned int result=30-__builtin_clz(size);
+    if(size & (size-1)) result++;
+    return result<<1;
+}
+
+//
+// class MPUConfiguration
+//
+
+MPUConfiguration::MPUConfiguration(unsigned int *elfBase, unsigned int elfSize,
+        unsigned int *imageBase, unsigned int imageSize)
+{
+    regValues[0]=(reinterpret_cast<unsigned int>(elfBase) & (~0x1f))
+               | MPU_RBAR_VALID_Msk | 0; //Region 0
+    regValues[2]=(reinterpret_cast<unsigned int>(imageBase) & (~0x1f))
+               | MPU_RBAR_VALID_Msk | 1; //Region 1
+    #ifndef __CODE_IN_XRAM
+    regValues[1]=2<<MPU_RASR_AP_Pos
+               | MPU_RASR_C_Msk
+               | 1 //Enable bit
+               | sizeToMpu(elfSize);
+    regValues[3]=3<<MPU_RASR_AP_Pos
+               | MPU_RASR_XN_Msk
+               | MPU_RASR_C_Msk
+               | MPU_RASR_S_Msk
+               | 1 //Enable bit
+               | sizeToMpu(imageSize);
+    #else //__CODE_IN_XRAM
+    regValues[1]=2<<MPU_RASR_AP_Pos
+               | MPU_RASR_C_Msk
+               | MPU_RASR_B_Msk
+               | MPU_RASR_S_Msk
+               | 1 //Enable bit
+               | sizeToMpu(elfSize);
+    regValues[3]=3<<MPU_RASR_AP_Pos
+               | MPU_RASR_XN_Msk
+               | MPU_RASR_C_Msk
+               | MPU_RASR_B_Msk
+               | MPU_RASR_S_Msk
+               | 1 //Enable bit
+               | sizeToMpu(imageSize);
+    #endif //__CODE_IN_XRAM
+}
+
+void MPUConfiguration::dumpConfiguration()
+{
+    for(int i=0;i<2;i++)
+    {
+        unsigned int base=regValues[2*i] & (~0x1f);
+        unsigned int end=base+(1<<(((regValues[2*i+1]>>1) & 31)+1));
+        char w=regValues[2*i+1] & (1<<MPU_RASR_AP_Pos) ? 'w' : '-';
+        char x=regValues[2*i+1] & MPU_RASR_XN_Msk ? '-' : 'x';
+        iprintf("* MPU region %d 0x%x-0x%x r%c%c\n",i,base,end,w,x);
+    }
+}
+
+bool MPUConfiguration::within(const unsigned int ptr) const
+{
+    unsigned int base = regValues[2] & (~0x1f);
+    unsigned int end = base + (1 << (((regValues[3] >> 1) & 31) + 1));
+    
+    return ptr >= base && ptr < end;
+}
+
+unsigned int MPUConfiguration::getBaseDataAddress() const
+{
+    return regValues[2] & (~0x1f);
+}
+
+unsigned int MPUConfiguration::getDataSize() const
+{
+    return (1 << (((regValues[3] >> 1) & 31) + 1));
+}
+
+#endif //WITH_PROCESSES
+
 void IRQportableStartKernel()
 {
     //Enable fault handlers
@@ -180,11 +368,16 @@ void IRQportableStartKernel()
     NVIC_SetPriorityGrouping(7);//This should disable interrupt nesting
     NVIC_SetPriority(SVCall_IRQn,3);//High priority for SVC (Max=0, min=15)
     NVIC_SetPriority(SysTick_IRQn,3);//High priority for SysTick (Max=0, min=15)
+    NVIC_SetPriority(MemoryManagement_IRQn,2);//Higher priority for MemoryManagement (Max=0, min=15)
     SysTick->LOAD=SystemCoreClock/miosix::TICK_FREQ;
     //Start SysTick, set to generate interrupts
     SysTick->CTRL=SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk |
             SysTick_CTRL_CLKSOURCE_Msk;
 
+    #ifdef WITH_PROCESSES
+    //Enable MPU
+    MPU->CTRL=MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk;
+    #endif //WITH_PROCESSES
     #ifdef SCHED_TYPE_CONTROL_BASED
     AuxiliaryTimer::IRQinit();
     #endif //SCHED_TYPE_CONTROL_BASED
diff --git a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability_impl.h b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability_impl.h
index 5fcc019b48c22748b3466d29368a89a918708327..47c48a267dd94580e45bbbd90cbf1bc3e3c50b01 100644
--- a/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability_impl.h
+++ b/miosix/arch/cortexM3_stm32f2/common/interfaces-impl/portability_impl.h
@@ -30,6 +30,7 @@
 #define PORTABILITY_IMPL_H
 
 #include "interfaces/arch_registers.h"
+#include "interfaces/portability.h"
 #include "config/miosix_settings.h"
 
 /**
@@ -43,7 +44,7 @@
  * context switch. It requires C linkage to be used inside asm statement.
  * Registers are saved in the following order:
  * *ctxsave+32 --> r11
- * *ctxsave+28 --> r10
+ * *ctxsave+28 --> r10        
  * *ctxsave+24 --> r9
  * *ctxsave+20 --> r8
  * *ctxsave+16 --> r7
@@ -102,7 +103,9 @@ namespace miosix_private {
 
 inline void doYield()
 {
-    asm volatile("svc 0");
+    asm volatile("movs r3, #0\n\t"
+                 "svc  0"
+                 :::"r3");
 }
 
 inline void doDisableInterrupts()
@@ -132,6 +135,68 @@ inline bool checkAreInterruptsEnabled()
     return true;
 }
 
+#ifdef WITH_PROCESSES
+
+//
+// class SyscallParameters
+//
+
+inline SyscallParameters::SyscallParameters(unsigned int *context) :
+        registers(reinterpret_cast<unsigned int*>(context[0])) {}
+
+inline int SyscallParameters::getSyscallId() const
+{
+    return registers[3];
+}
+
+inline unsigned int SyscallParameters::getFirstParameter() const
+{
+    return registers[0];
+}
+
+inline unsigned int SyscallParameters::getSecondParameter() const
+{
+    return registers[1];
+}
+
+inline unsigned int SyscallParameters::getThirdParameter() const
+{
+    return registers[2];
+}
+
+inline void SyscallParameters::setReturnValue(unsigned int ret)
+{
+    registers[0]=ret;
+}
+
+inline void portableSwitchToUserspace()
+{
+    asm volatile("movs r3, #1\n\t"
+                 "svc  0"
+                 :::"r3");
+}
+
+//
+// class MPU
+//
+
+inline void MPUConfiguration::IRQenable()
+{
+    MPU->RBAR=regValues[0];
+    MPU->RASR=regValues[1];
+    MPU->RBAR=regValues[2];
+    MPU->RASR=regValues[3];
+    __set_CONTROL(3); 
+}
+
+inline void MPUConfiguration::IRQdisable()
+{
+    __set_CONTROL(2);
+}
+
+
+#endif //WITH_PROCESSES
+
 /**
  * \}
  */
diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram.ld b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram.ld
index 78b66e0257f1f6a703f32ec04142ab9cb2c1e000..b0b9eedd4009218d0af49f780264f8f87181eeca 100644
--- a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram.ld
+++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram.ld
@@ -1,6 +1,7 @@
 /*
  * 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
  */
 
 /*
diff --git a/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram_processes.ld b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram_processes.ld
new file mode 100644
index 0000000000000000000000000000000000000000..89104ab0034ddc1d20aadbdb816504b78a4e1809
--- /dev/null
+++ b/miosix/arch/cortexM3_stm32f2/stm32f207ig_stm3220g-eval/stm32_1m+128k_all_in_xram_processes.ld
@@ -0,0 +1,145 @@
+/*
+ * 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:
+ * - all (code, .data, .bss, stacks, heap) in the external ram, using only
+ *   half of it (1MB).
+ * - the rest of the RAM (upper 1MB) is used as the process pool for allocating
+ *   processes.
+ * It is most useful for debugging, since powercycling the board will erase code
+ */
+
+/*
+ * The main stack is used for interrupt handling by the kernel.
+ * In this linker script the main stack is placed at the top of the ram since:
+ * - having 2MB of ram makes the "stack at bottom of ram" optimization useless
+ * - the interrupt vectors are forwarded at the bottom of the ram
+ */
+_main_stack_size   = 0x00000200;  /* main   stack size = 512Bytes */
+ASSERT(_main_stack_size   % 8 == 0, "MAIN stack size error");
+
+/* end of the stack */
+_main_stack_top = 0x64100000;                     /* placed at the top of ram */
+_heap_end = _main_stack_top - _main_stack_size;
+_process_pool_start = _main_stack_top;
+_process_pool_end = 0x64200000;
+
+/* identify the Entry Point  */
+ENTRY(_Z13Reset_Handlerv)
+
+/* specify the memory areas  */
+MEMORY
+{
+    ram(wx)     : ORIGIN = 0x64000000, LENGTH = 1M
+}
+
+/* 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))
+    } > ram
+
+    /* .ARM.exidx is sorted, so has to go in its own output section.  */
+    __exidx_start = .;
+    .ARM.exidx :
+    {
+        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+    } > ram
+    __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
+
+    /* .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/arch/cortexM4_stm32f4/common/CMSIS/core_cm4.h b/miosix/arch/cortexM4_stm32f4/common/CMSIS/core_cm4.h
index c7718bfa331cf081bab8eef8b42f13cb0d45edd1..98ec72ba5fd7edb8308cf4bdaad1395b5650c777 100644
--- a/miosix/arch/cortexM4_stm32f4/common/CMSIS/core_cm4.h
+++ b/miosix/arch/cortexM4_stm32f4/common/CMSIS/core_cm4.h
@@ -750,6 +750,26 @@ typedef struct
 #define MPU_RASR_ATTRS_Pos                 16                                             /*!< MPU RASR: MPU Region Attribute field Position */
 #define MPU_RASR_ATTRS_Msk                 (0xFFFFUL << MPU_RASR_ATTRS_Pos)               /*!< MPU RASR: MPU Region Attribute field Mask */
 
+//By TFT: copy-pasted those from core_cm3.h for compatibility -- begin
+#define MPU_RASR_XN_Pos                    28                                             /*!< MPU RASR: XN Position */
+#define MPU_RASR_XN_Msk                    (1ul << MPU_RASR_XN_Pos)                       /*!< MPU RASR: XN Mask */
+
+#define MPU_RASR_AP_Pos                    24                                             /*!< MPU RASR: AP Position */
+#define MPU_RASR_AP_Msk                    (7ul << MPU_RASR_AP_Pos)                       /*!< MPU RASR: AP Mask */
+
+#define MPU_RASR_TEX_Pos                   19                                             /*!< MPU RASR: TEX Position */
+#define MPU_RASR_TEX_Msk                   (7ul << MPU_RASR_TEX_Pos)                      /*!< MPU RASR: TEX Mask */
+
+#define MPU_RASR_S_Pos                     18                                             /*!< MPU RASR: Shareable bit Position */
+#define MPU_RASR_S_Msk                     (1ul << MPU_RASR_S_Pos)                        /*!< MPU RASR: Shareable bit Mask */
+
+#define MPU_RASR_C_Pos                     17                                             /*!< MPU RASR: Cacheable bit Position */
+#define MPU_RASR_C_Msk                     (1ul << MPU_RASR_C_Pos)                        /*!< MPU RASR: Cacheable bit Mask */
+
+#define MPU_RASR_B_Pos                     16                                             /*!< MPU RASR: Bufferable bit Position */
+#define MPU_RASR_B_Msk                     (1ul << MPU_RASR_B_Pos)                        /*!< MPU RASR: Bufferable bit Mask */
+//By TFT: copy-pasted those from core_cm3.h for compatibility -- end
+
 #define MPU_RASR_SRD_Pos                    8                                             /*!< MPU RASR: Sub-Region Disable Position */
 #define MPU_RASR_SRD_Msk                   (0xFFUL << MPU_RASR_SRD_Pos)                   /*!< MPU RASR: Sub-Region Disable Mask */
 
diff --git a/miosix/arch/cortexM4_stm32f4/common/core/interrupts.cpp b/miosix/arch/cortexM4_stm32f4/common/core/interrupts.cpp
index 411cbda4887cd546744aede791391c37e5e28403..40eb7a1b5192f4b8085c2e3d358c3d17abc32311 100644
--- a/miosix/arch/cortexM4_stm32f4/common/core/interrupts.cpp
+++ b/miosix/arch/cortexM4_stm32f4/common/core/interrupts.cpp
@@ -26,6 +26,7 @@
  ***************************************************************************/
 
 #include "kernel/logging.h"
+#include "kernel/kernel.h"
 #include "config/miosix_settings.h"
 #include "interfaces/portability.h"
 #include "interfaces/arch_registers.h"
@@ -54,34 +55,46 @@ static void printUnsignedInt(unsigned int x)
     IRQerrorLog(result);
 }
 
+#endif //WITH_ERRLOG
+
 /**
  * \internal
- * Print the program counter of the thread that was running when the exception
+ * \return the program counter of the thread that was running when the exception
  * occurred.
  */
-static void printProgramCounter()
+static unsigned int getProgramCounter()
 {
-    register unsigned int pc;
+    register unsigned int result;
     // Get program counter when the exception was thrown from stack frame
     asm volatile("mrs   %0,  psp    \n\t"
                  "add   %0, %0, #24 \n\t"
-                 "ldr   %0, [%0]    \n\t":"=r"(pc));
-    printUnsignedInt(pc);
+                 "ldr   %0, [%0]    \n\t":"=r"(result));
+    return result;
 }
 
-#endif //WITH_ERRLOG
-
 void NMI_Handler()
 {
     IRQerrorLog("\r\n***Unexpected NMI\r\n");
     miosix_private::IRQsystemReboot();
 }
 
-void HardFault_Handler()
+void __attribute__((naked)) HardFault_Handler()
 {
+    saveContext();
+    //Call HardFault_impl(). Name is a C++ mangled name.
+    asm volatile("bl _Z14HardFault_implv");
+    restoreContext();
+}
+
+void __attribute__((noinline)) HardFault_impl()
+{
+    #ifdef WITH_PROCESSES
+    if(miosix::Thread::IRQreportFault(miosix_private::FaultData(
+        HARDFAULT,getProgramCounter()))) return;
+    #endif //WITH_PROCESSES
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected HardFault @ ");
-    printProgramCounter();
+    printUnsignedInt(getProgramCounter());
     unsigned int hfsr=SCB->HFSR;
     if(hfsr & SCB_HFSR_FORCED_Msk)
         IRQerrorLog("Fault escalation occurred\r\n");
@@ -91,12 +104,32 @@ void HardFault_Handler()
     miosix_private::IRQsystemReboot();
 }
 
-void MemManage_Handler()
+void __attribute__((naked)) MemManage_Handler()
 {
+    saveContext();
+    //Call MemManage_impl(). Name is a C++ mangled name.
+    asm volatile("bl _Z14MemManage_implv");
+    restoreContext();
+}
+
+void __attribute__((noinline)) MemManage_impl()
+{
+    unsigned int cfsr=SCB->CFSR;
+    #ifdef WITH_PROCESSES
+    int id, arg=0;
+    if(cfsr & 0x00000001) id=MP_XN;
+    else if(cfsr & 0x00000080) { id=MP; arg=SCB->MMFAR; }
+    else id=MP_NOADDR;
+    if(miosix::Thread::IRQreportFault(miosix_private::FaultData(
+        id,getProgramCounter(),arg)))
+    {
+        SCB->SHCSR &= ~(1<<13); //Clear MEMFAULTPENDED bit
+        return;
+    }
+    #endif //WITH_PROCESSES
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected MemManage @ ");
-    printProgramCounter();
-    unsigned int cfsr=SCB->CFSR;
+    printUnsignedInt(getProgramCounter());
     if(cfsr & 0x00000080)
     {
         IRQerrorLog("Fault caused by attempted access to ");
@@ -118,7 +151,7 @@ void BusFault_Handler()
 {
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected BusFault @ ");
-    printProgramCounter();
+    printUnsignedInt(getProgramCounter());
     unsigned int cfsr=SCB->CFSR;
     if(cfsr & 0x00008000)
     {
@@ -139,12 +172,36 @@ void BusFault_Handler()
     miosix_private::IRQsystemReboot();
 }
 
-void UsageFault_Handler()
+void __attribute__((naked)) UsageFault_Handler()
+{
+    saveContext();
+    //Call UsageFault_impl(). Name is a C++ mangled name.
+    asm volatile("bl _Z15UsageFault_implv");
+    restoreContext();
+}
+
+void __attribute__((noinline)) UsageFault_impl()
 {
+    unsigned int cfsr=SCB->CFSR;
+    #ifdef WITH_PROCESSES
+    int id;
+    if(cfsr & 0x02000000) id=UF_DIVZERO;
+    else if(cfsr & 0x01000000) id=UF_UNALIGNED;
+    else if(cfsr & 0x00080000) id=UF_COPROC;
+    else if(cfsr & 0x00040000) id=UF_EXCRET;
+    else if(cfsr & 0x00020000) id=UF_EPSR;
+    else if(cfsr & 0x00010000) id=UF_UNDEF;
+    else id=UF_UNEXP;
+    if(miosix::Thread::IRQreportFault(miosix_private::FaultData(
+        id,getProgramCounter())))
+    {
+        SCB->SHCSR &= ~(1<<12); //Clear USGFAULTPENDED bit
+        return;
+    }
+    #endif //WITH_PROCESSES
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected UsageFault @ ");
-    printProgramCounter();
-    unsigned int cfsr=SCB->CFSR;
+    printUnsignedInt(getProgramCounter());
     if(cfsr & 0x02000000) IRQerrorLog("Divide by zero\r\n");
     if(cfsr & 0x01000000) IRQerrorLog("Unaligned memory access\r\n");
     if(cfsr & 0x00080000) IRQerrorLog("Attempted coprocessor access\r\n");
@@ -159,7 +216,7 @@ void DebugMon_Handler()
 {
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected DebugMon @ ");
-    printProgramCounter();
+    printUnsignedInt(getProgramCounter());
     #endif //WITH_ERRLOG
     miosix_private::IRQsystemReboot();
 }
@@ -168,7 +225,7 @@ void PendSV_Handler()
 {
     #ifdef WITH_ERRLOG
     IRQerrorLog("\r\n***Unexpected PendSV @ ");
-    printProgramCounter();
+    printUnsignedInt(getProgramCounter());
     #endif //WITH_ERRLOG
     miosix_private::IRQsystemReboot();
 }
diff --git a/miosix/arch/cortexM4_stm32f4/common/core/interrupts.h b/miosix/arch/cortexM4_stm32f4/common/core/interrupts.h
index 6b74a54ff907127a2719b87ddcae0e6b5a782fb7..cdb648f554046e8a59c519aa79826e1bf6f03620 100644
--- a/miosix/arch/cortexM4_stm32f4/common/core/interrupts.h
+++ b/miosix/arch/cortexM4_stm32f4/common/core/interrupts.h
@@ -34,4 +34,23 @@
  */
 void unexpectedInterrupt();
 
+/**
+ * Possible kind of faults that the Cortex-M3 can report.
+ * They are used to print debug information if a process causes a fault
+ */
+enum FaultType
+{
+    MP=1,          //Process attempted data access outside its memory
+    MP_NOADDR=2,   //Process attempted data access outside its memory (missing addr)
+    MP_XN=3,       //Process attempted code access outside its memory
+    UF_DIVZERO=4,  //Process attempted to divide by zero
+    UF_UNALIGNED=5,//Process attempted unaligned memory access
+    UF_COPROC=6,   //Process attempted a coprocessor access
+    UF_EXCRET=7,   //Process attempted an exception return
+    UF_EPSR=8,     //Process attempted to access the EPSR
+    UF_UNDEF=9,    //Process attempted to execute an invalid instruction
+    UF_UNEXP=10,   //Unexpected usage fault
+    HARDFAULT=11   //Hardfault (for example process executed a BKPT instruction)
+};
+
 #endif	//INTERRUPTS_H
diff --git a/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp b/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp
index 9700002290dfd1129ca3bc0be80baa28527084e2..8e85fe65fdfa7306de0e0e64e33bb9d78fe65b09 100644
--- a/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp
+++ b/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability.cpp
@@ -32,7 +32,11 @@
 #include "interfaces/bsp.h"
 #include "kernel/scheduler/scheduler.h"
 #include "kernel/scheduler/tick_interrupt.h"
+#include "core/interrupts.h"
 #include <algorithm>
+#include <cstdio>
+#include <cstring>
+#include <cassert>
 
 /**
  * \internal
@@ -111,8 +115,48 @@ void ISR_preempt()
 void ISR_yield() __attribute__((noinline));
 void ISR_yield()
 {
+    #ifdef WITH_PROCESSES
+    // WARNING: Temporary fix. Rationale:
+    // This fix is intended to avoid kernel or process faulting due to
+    // another process actions. Consider the case in which a process statically
+    // allocates a big array such that there is no space left for saving
+    // context data. If the process issues a system call, in the following
+    // interrupt the context is saved, but since there is no memory available
+    // for all the context data, a mem manage interrupt is set to 'pending'. Then,
+    // a fake syscall is issued, based on the value read on the stack (which
+    // the process hasn't set due to the memory fault and is likely to be 0);
+    // this syscall is usually a yield (due to the value of 0 above),
+    // which can cause the scheduling of the kernel thread. At this point,
+    // the pending mem fault is issued from the kernel thread, causing the
+    //kernel fault and reboot. This is caused by the mem fault interrupt
+    // having less priority of the other interrupts.
+    // This fix checks if there is a mem fault interrupt pending, and, if so,
+    // it clears it and returns before calling the previously mentioned fake
+    // syscall.
+    if(SCB->SHCSR & (1<<13))
+    {
+        if(miosix::Thread::IRQreportFault(miosix_private::FaultData(
+            MP,0,0)))
+        {
+            SCB->SHCSR &= ~(1<<13); //Clear MEMFAULTPENDED bit
+            return;
+        }
+    }
+    #endif // WITH_PROCESSES
     IRQstackOverflowCheck();
+    
+    #ifdef WITH_PROCESSES
+    //If processes are enabled, check the content of r3. If zero then it
+    //it is a simple yield, otherwise handle the syscall
+    //Note that it is required to use ctxsave and not cur->ctxsave because
+    //at this time we do not know if the active context is user or kernel
+    unsigned int threadSp=ctxsave[0];
+    unsigned int *processStack=reinterpret_cast<unsigned int*>(threadSp);
+    if(processStack[3]!=0) miosix::Thread::IRQhandleSvc(processStack[3]);
+    else miosix::Scheduler::IRQfindNextThread();
+    #else //WITH_PROCESSES
     miosix::Scheduler::IRQfindNextThread();
+    #endif //WITH_PROCESSES
 }
 
 #ifdef SCHED_TYPE_CONTROL_BASED
@@ -170,6 +214,150 @@ void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp,
     //leaving the content of s16-s31 uninitialized
 }
 
+#ifdef WITH_PROCESSES
+
+//
+// class FaultData
+//
+
+void FaultData::print() const
+{
+    switch(id)
+    {
+        case MP:
+            iprintf("* Attempted data access @ 0x%x (PC was 0x%x)\n",arg,pc);
+            break;
+        case MP_NOADDR:
+            iprintf("* Invalid data access (PC was 0x%x)\n",pc);
+            break;
+        case MP_XN:
+            iprintf("* Attempted instruction fetch @ 0x%x\n",pc);
+            break;
+        case UF_DIVZERO:
+            iprintf("* Dvide by zero (PC was 0x%x)\n",pc);
+            break;
+        case UF_UNALIGNED:
+            iprintf("* Unaligned memory access (PC was 0x%x)\n",pc);
+            break;
+        case UF_COPROC:
+            iprintf("* Attempted coprocessor access (PC was 0x%x)\n",pc);
+            break;
+        case UF_EXCRET:
+            iprintf("* Invalid exception return sequence (PC was 0x%x)\n",pc);
+            break;
+        case UF_EPSR:
+            iprintf("* Attempted access to the EPSR (PC was 0x%x)\n",pc);
+            break;
+        case UF_UNDEF:
+            iprintf("* Undefined instruction (PC was 0x%x)\n",pc);
+            break;
+        case UF_UNEXP:
+            iprintf("* Unexpected usage fault (PC was 0x%x)\n",pc);
+            break;
+        case HARDFAULT:
+            iprintf("* Hardfault (PC was 0x%x)\n",pc);
+            break;
+    }
+}
+
+void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp,
+        void *argv, unsigned int *gotBase)
+{
+    unsigned int *stackPtr=sp;
+    stackPtr--; //Stack is full descending, so decrement first
+    *stackPtr=0x01000000; stackPtr--;                                 //--> xPSR
+    *stackPtr=reinterpret_cast<unsigned long>(pc); stackPtr--;        //--> pc
+    *stackPtr=0xffffffff; stackPtr--;                                 //--> lr
+    *stackPtr=0; stackPtr--;                                          //--> r12
+    *stackPtr=0; stackPtr--;                                          //--> r3
+    *stackPtr=0; stackPtr--;                                          //--> r2
+    *stackPtr=0; stackPtr--;                                          //--> r1
+    *stackPtr=reinterpret_cast<unsigned long >(argv);                 //--> r0
+
+    ctxsave[0]=reinterpret_cast<unsigned long>(stackPtr);             //--> psp
+    ctxsave[6]=reinterpret_cast<unsigned long>(gotBase);              //--> r9 
+    //leaving the content of r4-r8,r10-r11 uninitialized
+}
+
+static unsigned int sizeToMpu(unsigned int size)
+{
+    assert(size>=32);
+    unsigned int result=30-__builtin_clz(size);
+    if(size & (size-1)) result++;
+    return result<<1;
+}
+
+//
+// class MPUConfiguration
+//
+
+MPUConfiguration::MPUConfiguration(unsigned int *elfBase, unsigned int elfSize,
+        unsigned int *imageBase, unsigned int imageSize)
+{
+    regValues[0]=(reinterpret_cast<unsigned int>(elfBase) & (~0x1f))
+               | MPU_RBAR_VALID_Msk | 0; //Region 0
+    regValues[2]=(reinterpret_cast<unsigned int>(imageBase) & (~0x1f))
+               | MPU_RBAR_VALID_Msk | 1; //Region 1
+    #ifndef __CODE_IN_XRAM
+    regValues[1]=2<<MPU_RASR_AP_Pos
+               | MPU_RASR_C_Msk
+               | 1 //Enable bit
+               | sizeToMpu(elfSize);
+    regValues[3]=3<<MPU_RASR_AP_Pos
+               | MPU_RASR_XN_Msk
+               | MPU_RASR_C_Msk
+               | MPU_RASR_S_Msk
+               | 1 //Enable bit
+               | sizeToMpu(imageSize);
+    #else //__CODE_IN_XRAM
+    regValues[1]=2<<MPU_RASR_AP_Pos
+               | MPU_RASR_C_Msk
+               | MPU_RASR_B_Msk
+               | MPU_RASR_S_Msk
+               | 1 //Enable bit
+               | sizeToMpu(elfSize);
+    regValues[3]=3<<MPU_RASR_AP_Pos
+               | MPU_RASR_XN_Msk
+               | MPU_RASR_C_Msk
+               | MPU_RASR_B_Msk
+               | MPU_RASR_S_Msk
+               | 1 //Enable bit
+               | sizeToMpu(imageSize);
+    #endif //__CODE_IN_XRAM
+}
+
+void MPUConfiguration::dumpConfiguration()
+{
+    for(int i=0;i<2;i++)
+    {
+        unsigned int base=regValues[2*i] & (~0x1f);
+        unsigned int end=base+(1<<(((regValues[2*i+1]>>1) & 31)+1));
+        char w=regValues[2*i+1] & (1<<MPU_RASR_AP_Pos) ? 'w' : '-';
+        char x=regValues[2*i+1] & MPU_RASR_XN_Msk ? '-' : 'x';
+        iprintf("* MPU region %d 0x%x-0x%x r%c%c\n",i,base,end,w,x);
+    }
+}
+
+bool MPUConfiguration::within(const unsigned int ptr) const
+{
+    unsigned int base = regValues[2] & (~0x1f);
+    unsigned int end = base + (1 << (((regValues[3] >> 1) & 31) + 1));
+    
+    return ptr >= base && ptr < end;
+}
+
+unsigned int MPUConfiguration::getBaseDataAddress() const
+{
+    return regValues[2] & (~0x1f);
+}
+
+unsigned int MPUConfiguration::getDataSize() const
+{
+    return (1 << (((regValues[3] >> 1) & 31) + 1));
+}
+
+#endif //WITH_PROCESSES
+
 void IRQportableStartKernel()
 {
     //Enable fault handlers
@@ -182,11 +370,16 @@ void IRQportableStartKernel()
     NVIC_SetPriorityGrouping(7);//This should disable interrupt nesting
     NVIC_SetPriority(SVCall_IRQn,3);//High priority for SVC (Max=0, min=15)
     NVIC_SetPriority(SysTick_IRQn,3);//High priority for SysTick (Max=0, min=15)
+    NVIC_SetPriority(MemoryManagement_IRQn,2);//Higher priority for MemoryManagement (Max=0, min=15)
     SysTick->LOAD=SystemCoreClock/miosix::TICK_FREQ;
     //Start SysTick, set to generate interrupts
     SysTick->CTRL=SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk |
             SysTick_CTRL_CLKSOURCE_Msk;
 
+    #ifdef WITH_PROCESSES
+    //Enable MPU
+    MPU->CTRL=MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk;
+    #endif //WITH_PROCESSES
     #ifdef SCHED_TYPE_CONTROL_BASED
     AuxiliaryTimer::IRQinit();
     #endif //SCHED_TYPE_CONTROL_BASED
diff --git a/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability_impl.h b/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability_impl.h
index e37f87b00c503f1c5d243049a922fd4ed15889c6..e80a2a4d9fe6de4ff2dd0f9929c9959cafcf7f7b 100644
--- a/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability_impl.h
+++ b/miosix/arch/cortexM4_stm32f4/common/interfaces-impl/portability_impl.h
@@ -30,6 +30,7 @@
 #define PORTABILITY_IMPL_H
 
 #include "interfaces/arch_registers.h"
+#include "interfaces/portability.h"
 #include "config/miosix_settings.h"
 
 /**
@@ -112,7 +113,9 @@ namespace miosix_private {
 
 inline void doYield()
 {
-    asm volatile("svc 0");
+    asm volatile("movs r3, #0\n\t"
+                 "svc  0"
+                 :::"r3");
 }
 
 inline void doDisableInterrupts()
@@ -142,6 +145,68 @@ inline bool checkAreInterruptsEnabled()
     return true;
 }
 
+#ifdef WITH_PROCESSES
+
+//
+// class SyscallParameters
+//
+
+inline SyscallParameters::SyscallParameters(unsigned int *context) :
+        registers(reinterpret_cast<unsigned int*>(context[0])) {}
+
+inline int SyscallParameters::getSyscallId() const
+{
+    return registers[3];
+}
+
+inline unsigned int SyscallParameters::getFirstParameter() const
+{
+    return registers[0];
+}
+
+inline unsigned int SyscallParameters::getSecondParameter() const
+{
+    return registers[1];
+}
+
+inline unsigned int SyscallParameters::getThirdParameter() const
+{
+    return registers[2];
+}
+
+inline void SyscallParameters::setReturnValue(unsigned int ret)
+{
+    registers[0]=ret;
+}
+
+inline void portableSwitchToUserspace()
+{
+    asm volatile("movs r3, #1\n\t"
+                 "svc  0"
+                 :::"r3");
+}
+
+//
+// class MPU
+//
+
+inline void MPUConfiguration::IRQenable()
+{
+    MPU->RBAR=regValues[0];
+    MPU->RASR=regValues[1];
+    MPU->RBAR=regValues[2];
+    MPU->RASR=regValues[3];
+    __set_CONTROL(3); 
+}
+
+inline void MPUConfiguration::IRQdisable()
+{
+    __set_CONTROL(2);
+}
+
+
+#endif //WITH_PROCESSES
+
 /**
  * \}
  */
diff --git a/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_rom_processes.ld b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_rom_processes.ld
new file mode 100644
index 0000000000000000000000000000000000000000..df941de32e53989da0020dcfbeb36df5909ccf78
--- /dev/null
+++ b/miosix/arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/stm32_1m+192k_rom_processes.ld
@@ -0,0 +1,179 @@
+/*
+ * C++ enabled linker script for stm32 (1M FLASH, 192K RAM)
+ * Developed by TFT: Terraneo Federico Technologies
+ * Optimized for use with the Miosix kernel
+ */
+
+/*
+ * This chip has an unusual quirk that the RAM is divided in two block mapped
+ * at two non contiguous memory addresses. I don't know why they've done that,
+ * probably doing the obvious thing would have made writing code too easy...
+ * Anyway, since hardware can't be changed, we've got to live with that and
+ * try to make use of both RAMs.
+ * 
+ * Given the constraints above, this linker script puts:
+ * - read only data and code (.text, .rodata, .eh_*) in FLASH
+ * - the 512Byte main (IRQ) stack, .data and .bss in the "small" 64KB RAM
+ * - stacks and heap in the "large" 128KB RAM.
+ * 
+ * Unfortunately thread stacks can't be put in the small RAM as Miosix
+ * allocates them inside the heap.
+ */
+
+/*
+ * 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  = 0x10000000 + _main_stack_size;
+ASSERT(_main_stack_size   % 8 == 0, "MAIN stack size error");
+
+/* Mapping the heap into the bottom 32KB of the large 128KB RAM */
+_end =      0x20000000;
+_heap_end = 0x20008000;
+/* Mapping the process pool into the upper 96KB of the large 128KB RAM */
+_process_pool_start = _heap_end;
+_process_pool_end = 0x20020000;                    /* end of available ram  */
+
+/* identify the Entry Point  */
+ENTRY(_Z13Reset_Handlerv)
+
+/* specify the memory areas  */
+MEMORY
+{
+    flash(rx)    : ORIGIN = 0x08000000, LENGTH =   1M
+    /*
+     * Note, the small ram starts at 0x10000000 but it is necessary to add the
+     * size of the main stack, so it is 0x10000200.
+     */
+    smallram(wx) : ORIGIN = 0x10000200, LENGTH =  64K-0x200 
+    largeram(wx) : ORIGIN = 0x20000000, LENGTH = 128K
+}
+
+/* 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 = .;
+    } > smallram AT > flash
+
+    /* .bss section: uninitialized global variables go to ram */
+    _bss_start = .;
+    .bss :
+    {
+        *(.bss)
+        *(.bss.*)
+        *(.gnu.linkonce.b.*)
+        . = ALIGN(8);
+    } > smallram
+    _bss_end = .;
+
+    /*_end = .;*/
+    /*PROVIDE(end = .);*/
+}
diff --git a/miosix/compiler/mx-postlinker/ELF.h b/miosix/compiler/mx-postlinker/ELF.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ec65f2013820c9ca6f3197b7997cf96fb0e6373
--- /dev/null
+++ b/miosix/compiler/mx-postlinker/ELF.h
@@ -0,0 +1,194 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Luigi Rucco and Terraneo Federico               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+#ifndef ELF_TYPES_H
+#define	ELF_TYPES_H
+
+#include <inttypes.h>
+
+// elf-specific types
+typedef uint32_t Elf32_Word;
+typedef int32_t  Elf32_Sword;
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Off;
+typedef uint32_t Elf32_Addr;
+
+// Size of e_ident in the elf header
+const int EI_NIDENT=16;
+
+/*
+ * Elf header
+ */
+struct Elf32_Ehdr
+{
+    unsigned char e_ident[EI_NIDENT]; // Ident bytes
+    Elf32_Half e_type;                // File type, any of the ET_* constants
+    Elf32_Half e_machine;             // Target machine
+    Elf32_Word e_version;             // File version
+    Elf32_Addr e_entry;               // Start address
+    Elf32_Off e_phoff;                // Phdr file offset
+    Elf32_Off e_shoff;                // Shdr file offset
+    Elf32_Word e_flags;               // File flags
+    Elf32_Half e_ehsize;              // Sizeof ehdr
+    Elf32_Half e_phentsize;           // Sizeof phdr
+    Elf32_Half e_phnum;               // Number phdrs
+    Elf32_Half e_shentsize;           // Sizeof shdr
+    Elf32_Half e_shnum;               // Number shdrs
+    Elf32_Half e_shstrndx;            // Shdr string index
+} __attribute__((packed));
+
+// Values for e_type
+const Elf32_Half ET_NONE = 0; // Unknown type
+const Elf32_Half ET_REL  = 1; // Relocatable
+const Elf32_Half ET_EXEC = 2; // Executable
+const Elf32_Half ET_DYN  = 3; // Shared object
+const Elf32_Half ET_CORE = 4; // Core file
+
+// Values for e_version
+const Elf32_Word EV_CURRENT = 1;
+
+// Values for e_machine
+const Elf32_Half EM_ARM  = 0x28;
+
+// Values for e_flags
+const Elf32_Word EF_ARM_EABI_MASK = 0x05000000;
+const Elf32_Word EF_HAS_ENTRY_POINT = 2;
+
+/*
+ * Elf program header
+ */
+struct Elf32_Phdr
+{
+    Elf32_Word p_type;   // Program header type, any of the PH_* constants
+    Elf32_Off  p_offset; // Segment start offset in file
+    Elf32_Addr p_vaddr;  // Segment virtual address
+    Elf32_Addr p_paddr;  // Segment physical address
+    Elf32_Word p_filesz; // Segment size in file
+    Elf32_Word p_memsz;  // Segment size in memory
+    Elf32_Word p_flags;  // Segment flasgs, any of the PF_* constants
+    Elf32_Word p_align;  // Segment alignment requirements
+} __attribute__((packed));
+
+// Values for p_type
+const Elf32_Word PT_NULL    = 0; // Unused array entry
+const Elf32_Word PT_LOAD    = 1; // Loadable segment
+const Elf32_Word PT_DYNAMIC = 2; // Segment is the dynamic section
+const Elf32_Word PT_INTERP  = 3; // Shared library interpreter
+const Elf32_Word PT_NOTE    = 4; // Auxiliary information
+
+// Values for p_flags
+const Elf32_Word PF_X = 0x1; // Execute
+const Elf32_Word PF_W = 0x2; // Write
+const Elf32_Word PF_R = 0x4; // Read
+
+/*
+ * Entries of the DYNAMIC segment
+ */
+struct Elf32_Dyn
+{
+    Elf32_Sword d_tag;    // Type of entry
+    union {
+        Elf32_Word d_val; // Value of entry, if number
+        Elf32_Addr d_ptr; // Value of entry, if offset into the file
+    } d_un;
+} __attribute__((packed));
+
+// Values for d_tag
+const int DT_NULL         = 0;
+const int DT_NEEDED       = 1;
+const int DT_PLTRELSZ     = 2;
+const int DT_PLTGOT       = 3;
+const int DT_HASH         = 4;
+const int DT_STRTAB       = 5;
+const int DT_SYMTAB       = 6;
+const int DT_RELA         = 7;
+const int DT_RELASZ       = 8;
+const int DT_RELAENT      = 9;
+const int DT_STRSZ        = 10;
+const int DT_SYMENT       = 11;
+const int DT_INIT         = 12;
+const int DT_FINI         = 13;
+const int DT_SONAME       = 14;
+const int DT_RPATH        = 15;
+const int DT_SYMBOLIC     = 16;
+const int DT_REL          = 17;
+const int DT_RELSZ        = 18;
+const int DT_RELENT       = 19;
+const int DT_PLTREL       = 20;
+const int DT_DEBUG        = 21;
+const int DT_TEXTREL      = 22;
+const int DT_JMPREL       = 23;
+const int DT_BINDNOW      = 24;
+const int DT_MX_RAMSIZE   = 0x10000000; //Miosix specific, RAM size
+const int DT_MX_STACKSIZE = 0x10000001; //Miosix specific, STACK size
+const int DT_MX_ABI       = 0x736f694d; //Miosix specific, ABI version
+const unsigned int DV_MX_ABI_V0 = 0x00007869; //Miosix specific, ABI version 0
+
+/*
+ * Relocation entries
+ */
+struct Elf32_Rel
+{
+    Elf32_Addr r_offset;
+    Elf32_Word r_info;
+} __attribute__((packed));
+
+// To extract the two fields of r_info
+#define ELF32_R_SYM(i) ((i)>>8)
+#define ELF32_R_TYPE(i) ((unsigned char)(i))
+
+// Possible values for ELF32_R_TYPE(r_info)
+const unsigned char R_ARM_NONE     = 0;
+const unsigned char R_ARM_ABS32    = 2;
+const unsigned char R_ARM_RELATIVE = 23;
+
+/*
+ * Elf Section header
+ */
+struct Elf32_Shdr
+{  
+  Elf32_Word sh_name;
+  Elf32_Word sh_type;
+  Elf32_Word sh_flags;
+  Elf32_Addr sh_addr;
+  Elf32_Off  sh_offset;
+  Elf32_Word sh_size;
+  Elf32_Word sh_link;
+  Elf32_Word sh_info;
+  Elf32_Word sh_addralign;
+  Elf32_Word sh_entsize;
+};
+
+// sh_type 
+const int SHT_NULL     =   0;               /* inactive */
+const int SHT_PROGBITS =   1;               /* program defined information */
+const int SHT_SYMTAB   =   2;               /* symbol table section */   
+const int SHT_STRTAB   =   3;               /* string table section */
+const int SHT_RELA     =   4;               /* relocation section with addends*/
+const int SHT_HASH     =   5;               /* symbol hash table section */
+const int SHT_DYNAMIC  =   6;               /* dynamic section */
+const int SHT_NOTE     =   7;               /* note section */
+const int SHT_NOBITS   =   8;               /* no space section */
+const int SHT_REL      =   9;               /* relation section without addends */
+const int SHT_SHLIB    =   10;              /* reserved - purpose unknown */
+const int SHT_DYNSYM   =   11;              /* dynamic symbol table section */
+const int SHT_LOPROC   =   0x70000000;      /* reserved range for processor */
+const int SHT_HIPROC   =   0x7fffffff;      /* specific section header types */
+const int SHT_LOUSER   =   0x80000000;      /* reserved range for application */
+const int SHT_HIUSER   =   0xffffffff;      /* specific indexes */
+
+#endif //ELF_TYPES_H
diff --git a/miosix/compiler/mx-postlinker/Makefile b/miosix/compiler/mx-postlinker/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..0252140b02eece7e5ef805c0677c6abf15cfcb5c
--- /dev/null
+++ b/miosix/compiler/mx-postlinker/Makefile
@@ -0,0 +1,21 @@
+CXX:= g++
+CXXFLAGS:= -O2 -c
+OBJS:= postlinker.o main.o
+DFLAGS:= -MMD -MP
+
+#create program target
+
+mx-postlinker: $(OBJS)
+	$(CXX) -o $@ $?
+
+install: mx-postlinker
+	cp mx-postlinker $(INSTALL_DIR)
+
+clean:
+	-rm mx-postlinker *.o *.d
+
+%.o: %.cpp
+	$(CXX) $(DFLAGS) $(CXXFLAGS) $? -o $@
+
+#pull in dependecy info for existing .o files
+-include $(OBJ:.o=.d)
diff --git a/miosix/compiler/mx-postlinker/main.cpp b/miosix/compiler/mx-postlinker/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cbec798f53cb07c0f00e24137070c3f15cf1a260
--- /dev/null
+++ b/miosix/compiler/mx-postlinker/main.cpp
@@ -0,0 +1,52 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Luigi Rucco and Terraneo Federico               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+#include <iostream>
+#include "postlinker.h"
+
+using namespace std;
+
+int main(int argc, char *argv[])
+{
+    int stackSize=-1;
+    int ramSize=-1;
+    string prog;
+    bool strip=false;
+    for(int i=1;i<argc;i++)
+    {
+        string opt(argv[i]);
+        if(opt=="--strip-sectheader")
+            strip=true;
+        else if(opt.substr(0,10)=="--ramsize=")
+            ramSize=atoi(opt.substr(10).c_str());
+        else if(opt.substr(0,12)=="--stacksize=")
+            stackSize=atoi(opt.substr(12).c_str());
+        else
+            prog=opt;
+    }
+    if(stackSize<=0 || ramSize<=0 || prog=="")
+    {
+        cerr<<"usage:"<<endl<<"mx-postlinker prog.elf --ramsize=<size>"
+            <<" --stacksize=<size> [--strip-sectheader]"<<endl;
+        return 1;
+    }
+    PostLinker pl(prog);
+    if(strip) pl.removeSectionHeaders();
+    pl.setMxTags(stackSize,ramSize);
+    pl.writeFile();
+    return 0;
+}
diff --git a/miosix/compiler/mx-postlinker/postlinker.cpp b/miosix/compiler/mx-postlinker/postlinker.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..83fa3b44a42aecc66aa48f431b6176a67c91cb5f
--- /dev/null
+++ b/miosix/compiler/mx-postlinker/postlinker.cpp
@@ -0,0 +1,120 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Luigi Rucco and Terraneo Federico               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+#include "postlinker.h"
+
+using namespace std;
+
+PostLinker::PostLinker(string s) 
+{
+    elfFile=s;
+    ifstream f(s.c_str(),ios::binary);
+    if(!f.good()) throw runtime_error("File not found");
+    f.seekg(0,ios::end);
+    size=f.tellg();
+    newSize=size;
+    f.seekg(0,ios::beg);
+    int roundedSize=(size+sizeof(Elf32_Word)-1) & ~(sizeof(Elf32_Word)-1);
+    elf=new Elf32_Word[roundedSize/sizeof(Elf32_Word)];
+    memset(elf,0,roundedSize);
+    f.read(reinterpret_cast<char*>(elf),size);
+    static const char magic[EI_NIDENT]={0x7f,'E','L','F',1,1,1};
+    if(size<sizeof(Elf32_Ehdr) || memcmp(getElfHeader()->e_ident,magic,EI_NIDENT))
+        throw runtime_error("Unrecognized format");
+}
+
+void PostLinker::removeSectionHeaders()
+{ 
+    newSize=getElfSection(getElfHeader()->e_shstrndx)->sh_offset;
+    getElfHeader()->e_shoff=0;
+    getElfHeader()->e_shnum=0;
+    getElfHeader()->e_shentsize=0;
+    getElfHeader()->e_shstrndx=0;
+}
+
+void PostLinker::setMxTags(int stackSize, int ramSize)
+{
+    if(stackSize & 0x3)
+        throw runtime_error("stack size not four word aligned");
+    if(ramSize & 0x3)
+        throw runtime_error("ram size not four word aligned");
+    if(getSizeOfDataAndBss()+stackSize>ramSize)
+        throw runtime_error(".data + .bss + stack exceeds ramsize");
+    getElfHeader()->e_type=ET_EXEC; //Force ET_EXEC
+    int ctr=0;
+    pair<Elf32_Dyn *,Elf32_Word> dyn=getDynamic();
+    for(int i=0;i<dyn.second;i++,dyn.first++)
+    {
+        if(dyn.first->d_tag!=DT_NULL) continue;
+        switch(ctr)
+        {
+            case 0:
+                dyn.first->d_tag=DT_MX_RAMSIZE;
+                dyn.first->d_un.d_val=ramSize;
+                break;
+            case 1:
+                dyn.first->d_tag=DT_MX_STACKSIZE;
+                dyn.first->d_un.d_val=stackSize;
+                break;
+            case 2:
+                dyn.first->d_tag=DT_MX_ABI;
+                dyn.first->d_un.d_val=DV_MX_ABI_V0;
+                return;
+        }
+        ctr++;     
+    }
+    throw runtime_error("Not enough null entries");
+}
+
+void PostLinker::writeFile()
+{
+    ofstream o(elfFile.c_str(),ios::binary);
+    o.write(reinterpret_cast<char*>(elf),newSize);
+}
+
+pair<Elf32_Dyn *,Elf32_Word> PostLinker::getDynamic()
+{
+    for(int i=0;i<getElfHeader()->e_phnum;i++)
+    {
+        Elf32_Phdr* phdr=getElfSegment(i);
+        if(phdr->p_type!=PT_DYNAMIC) continue;
+        unsigned char *base=reinterpret_cast<unsigned char*>(elf);
+        unsigned int offset=phdr->p_offset;
+        if(offset+phdr->p_memsz>size)
+            throw std::runtime_error("Dynamic outside file bounds");
+        return make_pair(reinterpret_cast<Elf32_Dyn*>(base+offset),
+                phdr->p_memsz/sizeof(Elf32_Dyn));
+    }
+    throw runtime_error("Dynamic not found");
+}
+
+int PostLinker::getSizeOfDataAndBss()
+{
+    for(int i=0;i<getElfHeader()->e_phnum;i++)
+    {
+        Elf32_Phdr* phdr=getElfSegment(i);
+        if(phdr->p_type!=PT_LOAD) continue;
+        if(!(phdr->p_flags & PF_W) || (phdr->p_flags & PF_X)) continue;
+        return phdr->p_memsz;
+    }
+    throw runtime_error(".data/.bss not found");
+}
+
+PostLinker::~PostLinker() 
+{
+    delete[] elf;
+}
diff --git a/miosix/compiler/mx-postlinker/postlinker.h b/miosix/compiler/mx-postlinker/postlinker.h
new file mode 100644
index 0000000000000000000000000000000000000000..24b205706196f7bedab884c899cfd821e7f27b58
--- /dev/null
+++ b/miosix/compiler/mx-postlinker/postlinker.h
@@ -0,0 +1,127 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Luigi Rucco and Terraneo Federico               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+#ifndef POSTLINKER_H
+#define	POSTLINKER_H
+
+#include "ELF.h"
+#include <cstring>
+#include <iostream>
+#include <exception>
+#include <stdexcept>
+#include <utility>
+#include <cstdlib>
+#include <fstream>
+
+/**
+ * This class performs transformations on an elf file,
+ * including stripping the section header and associated
+ * string table, and setting some Miosix specific options
+ * in the dynamic segment
+ */
+class PostLinker
+{
+public:
+    /**
+     * Constructor
+     * \param s elf file name 
+     */
+    PostLinker(std::string s);
+
+    /**
+     * Remove the section header and string table from the elf file
+     */
+    void removeSectionHeaders();
+
+    /**
+     * Set the Miosix specific options in the dynamic segment
+     * \param stackSize size that the runtime linker-loader will reserve for
+     * the stack of the process
+     * \param ramSize size of the process RAM image that the runtime
+     * linker-loader will allocate for the process
+     */
+    void setMxTags(int stackSize, int ramSize);
+
+    /**
+     * Write changes to disk
+     */
+    void writeFile();
+
+    /**
+     * Destructor
+     */
+    ~PostLinker();
+    
+private:
+    PostLinker(const PostLinker&);
+    PostLinker& operator= (const PostLinker&);
+
+    /**
+     * \return the elf header
+     */
+    Elf32_Ehdr* getElfHeader()
+    {
+        return reinterpret_cast<Elf32_Ehdr*>(elf);
+    }
+
+    /**
+     * Allows to retrieve a section header given its index
+     * \param index a index from 0 to getElfHeader()->e_shnum
+     * \return the corresponding section header
+     */
+    Elf32_Shdr* getElfSection(int index)
+    {
+        unsigned char *base=reinterpret_cast<unsigned char*>(elf);
+        unsigned int offset=getElfHeader()->e_shoff+index*sizeof(Elf32_Shdr);
+        if(offset+sizeof(Elf32_Shdr)>size)
+            throw std::runtime_error("Elf section outside file bounds");
+        return reinterpret_cast<Elf32_Shdr*>(base+offset);
+    }
+    
+    /**
+     * Allows to retrieve a segment header given its index
+     * \param index a index from 0 to getElfHeader()->e_phnum
+     * \return the corresponding secgment header
+     */
+    Elf32_Phdr *getElfSegment(int index)
+    {
+        unsigned char *base=reinterpret_cast<unsigned char*>(elf);
+        unsigned int offset=getElfHeader()->e_phoff+index*sizeof(Elf32_Phdr);
+        if(offset+sizeof(Elf32_Phdr)>size)
+            throw std::runtime_error("Elf segment outside file bounds");
+        return reinterpret_cast<Elf32_Phdr*>(base+offset);
+    }
+    
+    /**
+     * \return the size of the segment that is loaded in RAM, with
+     * .data and .bss
+     */
+    int getSizeOfDataAndBss();
+    
+    /**
+     * \return a pair with a pointer to the first element in the dynamic
+     * segment and the number of entries in the dynamic segment
+     */
+    std::pair<Elf32_Dyn *,Elf32_Word> getDynamic();
+    
+    Elf32_Word* elf;
+    int size;
+    int newSize;
+    std::string elfFile;
+};
+
+#endif	//POSTLINKER_H
diff --git a/miosix/config/Makefile.inc b/miosix/config/Makefile.inc
index 171181a41165252e7ab0549739b28fd3d1287190..7aaca4d797a1c0457fc5e6a8dfe84846429d3ec2 100644
--- a/miosix/config/Makefile.inc
+++ b/miosix/config/Makefile.inc
@@ -134,9 +134,12 @@ ifeq ($(OPT_BOARD),stm32f407vg_stm32f4discovery)
     ## Linker script type, there are two options
     ## 1) Code in FLASH, stack + heap in internal RAM (file *_rom.ld)
     ## 2) Code + stack + heap in internal RAM (file *_ram.ld)
+    ## 3) Same as 1) but space has been reserved for a process pool, allowing
+    ##    to configure the kernel with "#define WITH_PROCESSES"
     LINKER_SCRIPT_PATH := arch/cortexM4_stm32f4/stm32f407vg_stm32f4discovery/
     LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+192k_rom.ld
     #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+192k_ram.ld
+    #LINKER_SCRIPT := $(LINKER_SCRIPT_PATH)stm32_1m+192k_rom_processes.ld
 
     ## This causes the interrupt vector table to be relocated in SRAM, must be
     ## uncommented when using the ram linker script
@@ -165,12 +168,15 @@ ifeq ($(OPT_BOARD),stm32f207ig_stm3220g-eval)
     ##    forwards interrrupts @ 0x64000000 (see miosix/_tools/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_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
@@ -747,7 +753,7 @@ else ifeq ($(ARCH),cortexM3_stm32f2)
         PROGRAM_CMDLINE := miosix/_tools/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/config/miosix_settings.h b/miosix/config/miosix_settings.h
index 0c1cd482276c7dd59da6e3e0d6c22a6ed4dca4c3..475b1a7342cd59e5cf9658839223f0215e3648d6 100644
--- a/miosix/config/miosix_settings.h
+++ b/miosix/config/miosix_settings.h
@@ -61,6 +61,17 @@ namespace miosix {
 #define SCHED_TYPE_PRIORITY
 //#define SCHED_TYPE_CONTROL_BASED
 //#define SCHED_TYPE_EDF
+    
+/// \def WITH_PROCESSES
+/// If uncommented enables support for processes as well as threads.
+/// This enables the dynamic loader to load elf programs, the extended system
+/// call service and, if the hardware supports it, the MPU to provide memory
+/// isolation of processes
+//#define WITH_PROCESSES
+
+#if defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS)
+#error Processes require C++ exception support
+#endif //defined(WITH_PROCESSES) && defined(__NO_EXCEPTIONS)
 
 //
 // Filesystem options
@@ -128,6 +139,20 @@ const unsigned int STACK_IDLE=256;
 /// such as printf/fopen which are stack-heavy
 const unsigned int STACK_DEFAULT_FOR_PTHREAD=2048;
 
+/// Maximum size of the RAM image of a process. If a program requires more
+/// the kernel will not run it (MUST be divisible by 4)
+const unsigned int MAX_PROCESS_IMAGE_SIZE=64*1024;
+
+/// Minimum size of the stack for a process. If a program specifies a lower
+/// size the kernel will not run it (MUST be divisible by 4)
+const unsigned int MIN_PROCESS_STACK_SIZE=STACK_MIN;
+
+/// Every userspace thread has two stacks, one for when it is running in
+/// userspace and one for when it is running in kernelspace (that is, while it
+/// is executing system calls). This is the size of the stack for when the
+/// thread is running in kernelspace (MUST be divisible by 4)
+const unsigned int SYSTEM_MODE_PROCESS_STACK_SIZE=2*1024;
+
 /// Number of priorities (MUST be >1)
 /// PRIORITY_MAX-1 is the highest priority, 0 is the lowest. -1 is reserved as
 /// the priority of the idle thread.
diff --git a/miosix/interfaces/portability.h b/miosix/interfaces/portability.h
index b1c7a807b41ff8f63e37dede2805df712f1cf9ab..0cf3e500c4c52564861c35568b1e47beacb146cd 100644
--- a/miosix/interfaces/portability.h
+++ b/miosix/interfaces/portability.h
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2010 by Terraneo Federico                               *
+ *   Copyright (C) 2010, 2011, 2012 by Terraneo Federico                   *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -49,6 +49,16 @@
  * This file should contain the implementation of those inline functions.
  */
 
+#ifdef WITH_PROCESSES
+
+namespace miosix {
+
+class Process; //Forward decl
+
+} //namespace miosix
+
+#endif //WITH_PROCESSES
+
 /**
  * \}
  */
@@ -99,6 +109,185 @@ inline void doYield();
 void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp,
         void *argv);
 
+#ifdef WITH_PROCESSES
+
+/**
+ * This class allows to access the parameters that a process passed to
+ * the operating system as part of a system call
+ */
+class SyscallParameters
+{
+public:
+    /**
+     * Constructor, initialize the class starting from the thread's userspace
+     * context
+     */
+    SyscallParameters(unsigned int *context);
+    
+    /**
+     * \return the syscall id, used to identify individual system calls
+     */
+    int getSyscallId() const;
+    
+    /**
+     * \return the first syscall parameter. The returned result is meaningful
+     * only if the syscall (identified through its id) has one or more parameters
+     */
+    unsigned int getFirstParameter() const;
+    
+    /**
+     * \return the second syscall parameter. The returned result is meaningful
+     * only if the syscall (identified through its id) has two or more parameters
+     */
+    unsigned int getSecondParameter() const;
+    
+    /**
+     * \return the third syscall parameter. The returned result is meaningful
+     * only if the syscall (identified through its id) has three parameters
+     */
+    unsigned int getThirdParameter() const;
+    
+    /**
+     * Set the value that will be returned by the syscall.
+     * Invalidates parameters so must be called only after the syscall
+     * parameteres have been read.
+     * \param ret value that will be returned by the syscall.
+     */
+    void setReturnValue(unsigned int ret);
+    
+private:
+    unsigned int *registers;
+};
+
+/**
+ * This class contains information about whether a fault occurred in a process.
+ * It is used to terminate processes that fault.
+ */
+class FaultData
+{
+public:
+    /**
+     * Constructor, initializes the object
+     */
+    FaultData() : id(0) {}
+    
+    /**
+     * Constructor, initializes a FaultData object
+     * \param id id of the fault
+     * \param pc program counter at the moment of the fault
+     * \param arg eventual additional argument, depending on the fault id
+     */
+    FaultData(int id, unsigned int pc, unsigned int arg=0)
+            : id(id), pc(pc), arg(arg) {}
+    
+    /**
+     * \return true if a fault happened within a process
+     */
+    bool faultHappened() const { return id!=0; }
+    
+    /**
+     * Print information about the occurred fault
+     */
+    void print() const;
+    
+private:
+    int id; ///< Id of the fault or zero if no faults
+    unsigned int pc; ///< Program counter value at the time of the fault
+    unsigned int arg;///< Eventual argument, valid only for some id values
+};
+
+/**
+ * \internal
+ * Initializes a ctxsave array when a thread is created.
+ * This version is to initialize the userspace context of processes.
+ * It is used by the kernel, and should not be used by end users.
+ * \param ctxsave a pointer to a field ctxsave inside a Thread class that need
+ * to be filled
+ * \param pc starting program counter of newly created thread, used to
+ * initialize ctxsave
+ * \param sp starting stack pointer of newly created thread, used to initialize
+ * ctxsave
+ * \param argv starting data passed to newly created thread, used to initialize
+ * ctxsave
+ * \param gotBase base address of the global offset table, for userspace
+ * processes
+ */
+void initCtxsave(unsigned int *ctxsave, void *(*pc)(void *), unsigned int *sp,
+        void *argv, unsigned int *gotBase);
+
+/**
+ * \internal
+ * Cause a supervisor call that will switch the thread back to kernelspace
+ * It is used by the kernel, and should not be used by end users.
+ */
+inline void portableSwitchToUserspace();
+
+/**
+ * \internal
+ * This class is used to manage the MemoryProtectionUnit
+ */
+
+class MPUConfiguration
+{
+ public:
+     /**
+      * Default constructor, leaves the MPU regions unconfigured
+      */
+     MPUConfiguration() {}
+     
+     /**
+      * \internal
+      * \param elfBase base address of the ELF file
+      * \param elfSize size of the ELF file
+      * \param imageBase base address of the Process RAM image
+      * \param imageSize size of the Process RAM image
+      */
+     MPUConfiguration(unsigned int *elfBase, unsigned int elfSize,
+             unsigned int *imageBase, unsigned int imageSize);
+     
+     /**
+      * \internal
+      * This method is used to configure the Memoy Protection region for a 
+      * Process during a context-switch to a userspace thread.
+      * Can only be called inside an IRQ, not even with interrupts disabled
+      */
+     void IRQenable();
+     
+     /**
+      * \internal
+      * This method is used to disable the MPU during a context-switch to a
+      * kernelspace thread.
+      * Can only be called inside an IRQ, not even with interrupts disabled
+      */
+     static void IRQdisable();
+     
+     /**
+      * Print the MPU configuration for debugging purposes
+      */
+     void dumpConfiguration();
+	 
+	 /**
+	  * Check if the address is within the data segment
+      * \param ptr the address of the pointer
+      * \return  true if the pointer points within the data segment,
+      * false otherwise.
+      */
+	 bool within(const unsigned int ptr) const;
+	 
+	 /**
+	  * \internal
+	  */
+	 unsigned int getBaseDataAddress() const;
+	 unsigned int getDataSize() const;
+ 
+     //Uses default copy constructor and operator=
+private:
+     ///These value are copied into the MPU registers to configure them
+     unsigned int regValues[4]; 
+};
+
+#endif //WITH_PROCESSES
+
 /**
  * \internal
  * Used before every context switch to check if the stack of the thread has
diff --git a/miosix/kernel/SystemMap.cpp b/miosix/kernel/SystemMap.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e45eb34cf7c425097222c66f55dd8faa0913ba13
--- /dev/null
+++ b/miosix/kernel/SystemMap.cpp
@@ -0,0 +1,49 @@
+
+#include "SystemMap.h"
+
+using namespace std;
+
+#ifdef WITH_PROCESSES
+
+namespace miosix {
+
+SystemMap& SystemMap::instance()
+{
+    static SystemMap singleton;
+    return singleton;
+}
+
+void SystemMap::addElfProgram(const char* name, const unsigned int *elf, unsigned int size)
+{
+    string sName(name);
+    if(mPrograms.find(sName) == mPrograms.end())
+        mPrograms.insert(make_pair(sName, make_pair(elf, size)));
+}
+
+void SystemMap::removeElfProgram(const char* name)
+{
+    string sName(name);
+    ProgramsMap::iterator it = mPrograms.find(sName);
+
+    if(it != mPrograms.end())
+        mPrograms.erase(it);
+}
+
+pair<const unsigned int*, unsigned int>  SystemMap::getElfProgram(const char* name) const
+{
+    ProgramsMap::const_iterator it = mPrograms.find(string(name));
+
+    if(it == mPrograms.end())
+        return make_pair<const unsigned int*, unsigned int>(0, 0);
+
+    return it->second;
+}
+
+unsigned int SystemMap::getElfCount() const
+{
+    return mPrograms.size();
+}
+
+} //namespace miosix
+
+#endif //WITH_PROCESSES
diff --git a/miosix/kernel/SystemMap.h b/miosix/kernel/SystemMap.h
new file mode 100644
index 0000000000000000000000000000000000000000..7094420d0113e434ea1f901ccb5ef62fffa04768
--- /dev/null
+++ b/miosix/kernel/SystemMap.h
@@ -0,0 +1,38 @@
+#ifndef SYSTEMMAP_H
+#define	SYSTEMMAP_H
+
+#include "kernel/sync.h"
+#include "config/miosix_settings.h"
+
+#include <map>
+#include <string>
+
+#ifdef WITH_PROCESSES
+
+namespace miosix {
+
+class SystemMap
+{
+public:
+    static SystemMap &instance();
+
+    void addElfProgram(const char *name, const unsigned int *elf, unsigned int size);
+    void removeElfProgram(const char *name);
+    std::pair<const unsigned int*, unsigned int> getElfProgram(const char *name) const;
+
+    unsigned int getElfCount() const;
+
+private:
+    SystemMap() {}
+    SystemMap(const SystemMap&);
+    SystemMap& operator= (const SystemMap&);
+
+    typedef std::map<std::string, std::pair<const unsigned int*, unsigned int> > ProgramsMap;
+    ProgramsMap mPrograms;
+};
+
+} //namespace miosix
+
+#endif //WITH_PROCESSES
+
+#endif	/* SYSTEMMAP_H */
diff --git a/miosix/kernel/elf_program.cpp b/miosix/kernel/elf_program.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bab4deae6655461392d5eccc93a0bdba44a2c547
--- /dev/null
+++ b/miosix/kernel/elf_program.cpp
@@ -0,0 +1,321 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Terraneo Federico                               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+#include "elf_program.h"
+#include "process_pool.h"
+#include <stdexcept>
+#include <cstring>
+#include <cstdio>
+
+using namespace std;
+
+#ifdef WITH_PROCESSES
+
+namespace miosix {
+
+///\internal Enable/disable debugging of program loading
+//#define DBG iprintf
+#define DBG(x,...) ;
+    
+///By convention, in an elf file for Miosix, the data segment starts @ this addr
+static const unsigned int DATA_START=0x10000000;
+
+//
+// class ElfProgram
+//
+
+ElfProgram::ElfProgram(const unsigned int *elf, unsigned int size)
+    : elf(elf), size(size)
+{
+    //Trying to follow the "full recognition before processing" approach,
+    //(http://www.cs.dartmouth.edu/~sergey/langsec/occupy/FullRecognition.jpg)
+    //all of the elf fields that will later be used are checked in advance.
+    //Unused fields are unchecked, so when using new fields, add new checks
+    if(validateHeader()==false) throw runtime_error("Bad file");
+}
+
+bool ElfProgram::validateHeader()
+{
+    //Validate ELF header
+    //Note: this code assumes a little endian elf and a little endian ARM CPU
+    if(size<sizeof(Elf32_Ehdr)) return false;
+    const Elf32_Ehdr *ehdr=getElfHeader();
+    static const char magic[EI_NIDENT]={0x7f,'E','L','F',1,1,1};
+    if(memcmp(ehdr->e_ident,magic,EI_NIDENT))
+        throw runtime_error("Unrecognized format");
+    if(ehdr->e_type!=ET_EXEC) throw runtime_error("Not an executable");
+    if(ehdr->e_machine!=EM_ARM) throw runtime_error("Wrong CPU arch");
+    if(ehdr->e_version!=EV_CURRENT) return false;
+    if(ehdr->e_entry>=size) return false;
+    if(ehdr->e_phoff>=size-sizeof(Elf32_Phdr)) return false;
+    if(ehdr->e_flags!=(EF_ARM_EABI_MASK | EF_HAS_ENTRY_POINT)) return false;
+    if(ehdr->e_ehsize!=sizeof(Elf32_Ehdr)) return false;
+    if(ehdr->e_phentsize!=sizeof(Elf32_Phdr)) return false;
+    //This to avoid that the next condition could pass due to 32bit wraparound
+    //20 is an arbitrary number, could be increased if required
+    if(ehdr->e_phnum>20) throw runtime_error("Too many segments");
+    if(ehdr->e_phoff+(ehdr->e_phnum*sizeof(Elf32_Phdr))>size) return false;
+    
+    //Validate program header table
+    bool codeSegmentPresent=false;
+    bool dataSegmentPresent=false;
+    bool dynamicSegmentPresent=false;
+    int dataSegmentSize=0;
+    const Elf32_Phdr *phdr=getProgramHeaderTable();
+    for(int i=0;i<getNumOfProgramHeaderEntries();i++,phdr++)
+    {
+        //The third condition does not imply the other due to 32bit wraparound
+        if(phdr->p_offset>=size) return false;
+        if(phdr->p_filesz>=size) return false;
+        if(phdr->p_offset+phdr->p_filesz>size) return false;
+        
+        if(phdr->p_align>8) throw runtime_error("Segment alignment too strict");
+        
+        switch(phdr->p_type)
+        {
+            case PT_LOAD:
+                if(phdr->p_flags & ~(PF_R | PF_W | PF_X)) return false;
+                if(!(phdr->p_flags & PF_R)) return false;
+                if((phdr->p_flags & PF_W) && (phdr->p_flags & PF_X))
+                    throw runtime_error("File violates W^X");
+                if(phdr->p_flags & PF_X)
+                {
+                    if(codeSegmentPresent) return false; //Can't apper twice
+                    codeSegmentPresent=true;
+                    if(ehdr->e_entry<phdr->p_offset ||
+                       ehdr->e_entry>phdr->p_offset+phdr->p_filesz ||
+                       phdr->p_filesz!=phdr->p_memsz) return false;
+                }
+                if((phdr->p_flags & PF_W) && !(phdr->p_flags & PF_X))
+                {
+                    if(dataSegmentPresent) return false; //Two data segments?
+                    dataSegmentPresent=true;
+                    if(phdr->p_memsz<phdr->p_filesz) return false;
+                    unsigned int maxSize=MAX_PROCESS_IMAGE_SIZE-
+                        MIN_PROCESS_STACK_SIZE;
+                    if(phdr->p_memsz>=maxSize)
+                        throw runtime_error("Data segment too big");
+                    dataSegmentSize=phdr->p_memsz;
+                }
+                break;
+            case PT_DYNAMIC:
+                if(dynamicSegmentPresent) return false; //Two dynamic segments?
+                dynamicSegmentPresent=true;
+                //DYNAMIC segment *must* come after data segment
+                if(dataSegmentPresent==false) return false;
+                if(validateDynamicSegment(phdr,dataSegmentSize)==false)
+                    return false;
+                break;
+            default:
+                //Ignoring other segments
+                break;
+        }
+    }
+    if(codeSegmentPresent==false) return false; //Can't not have code segment
+    return true;
+}
+
+bool ElfProgram::validateDynamicSegment(const Elf32_Phdr *dynamic,
+        unsigned int dataSegmentSize)
+{
+    unsigned int base=getElfBase();
+    const Elf32_Dyn *dyn=
+        reinterpret_cast<const Elf32_Dyn*>(getElfBase()+dynamic->p_offset);
+    const int dynSize=dynamic->p_memsz/sizeof(Elf32_Dyn);
+    Elf32_Addr dtRel=0;
+    Elf32_Word dtRelsz=0;
+    unsigned int hasRelocs=0;
+    bool miosixTagFound=false;
+    unsigned int ramSize=0;
+    unsigned int stackSize=0;
+    for(int i=0;i<dynSize;i++,dyn++)
+    {
+        switch(dyn->d_tag)
+        {
+            case DT_REL:
+                hasRelocs |= 0x1;
+                dtRel=dyn->d_un.d_ptr;
+                break;
+            case DT_RELSZ:
+                hasRelocs |= 0x2;
+                dtRelsz=dyn->d_un.d_val;
+                break;
+            case DT_RELENT:
+                hasRelocs |= 0x4;
+                if(dyn->d_un.d_val!=sizeof(Elf32_Rel)) return false;
+                break;  
+            case DT_MX_ABI:
+                if(dyn->d_un.d_val==DV_MX_ABI_V0) miosixTagFound=true;
+                break;
+            case DT_MX_RAMSIZE:
+                ramSize=dyn->d_un.d_val;
+                break;
+            case DT_MX_STACKSIZE:
+                stackSize=dyn->d_un.d_val;
+                break;
+            case DT_RELA:
+            case DT_RELASZ:
+            case DT_RELAENT:
+                throw runtime_error("RELA relocations unsupported");
+            default:
+                //Ignore other entries
+                break;
+        }
+    }
+    if(miosixTagFound==false) throw runtime_error("Not a Miosix executable");
+    if(stackSize<MIN_PROCESS_STACK_SIZE)
+        throw runtime_error("Requested stack is too small");
+    if(ramSize>MAX_PROCESS_IMAGE_SIZE)
+        throw runtime_error("Requested image size is too large");
+    if((stackSize & 0x3) ||
+       (ramSize & 0x3) ||
+       (ramSize < ProcessPool::blockSize) ||
+       (stackSize>MAX_PROCESS_IMAGE_SIZE) ||
+       (dataSegmentSize>MAX_PROCESS_IMAGE_SIZE) ||
+       (dataSegmentSize+stackSize>ramSize))
+        throw runtime_error("Invalid stack or RAM size");
+    
+    if(hasRelocs!=0 && hasRelocs!=0x7) return false;
+    if(hasRelocs)
+    {
+        //The third condition does not imply the other due to 32bit wraparound
+        if(dtRel>=size) return false;
+        if(dtRelsz>=size) return false;
+        if(dtRel+dtRelsz>size) return false;
+        
+        const Elf32_Rel *rel=reinterpret_cast<const Elf32_Rel*>(base+dtRel);
+        const int relSize=dtRelsz/sizeof(Elf32_Rel);
+        for(int i=0;i<relSize;i++,rel++)
+        {
+            switch(ELF32_R_TYPE(rel->r_info))
+            {
+                case R_ARM_NONE:
+                    break;
+                case R_ARM_RELATIVE:
+                    if(rel->r_offset<DATA_START) return false;
+                    if(rel->r_offset>DATA_START+dataSegmentSize-4) return false;
+                    if(rel->r_offset & 0x3) return false;
+                    break;
+                default:
+                    throw runtime_error("Unexpected relocation type");
+            }
+        }
+    }
+    return true;
+}
+
+//
+// class ProcessImage
+//
+
+void ProcessImage::load(const ElfProgram& program)
+{
+    if(image) ProcessPool::instance().deallocate(image);
+    const unsigned int base=program.getElfBase();
+    const Elf32_Phdr *phdr=program.getProgramHeaderTable();
+    const Elf32_Phdr *dataSegment=0;
+    Elf32_Addr dtRel=0;
+    Elf32_Word dtRelsz=0;
+    bool hasRelocs=false;
+    for(int i=0;i<program.getNumOfProgramHeaderEntries();i++,phdr++)
+    {
+        switch(phdr->p_type)
+        {
+            case PT_LOAD:
+                if((phdr->p_flags & PF_W) && !(phdr->p_flags & PF_X))
+                    dataSegment=phdr;
+                break;
+            case PT_DYNAMIC:
+            {
+                const Elf32_Dyn *dyn=reinterpret_cast<const Elf32_Dyn*>
+                    (base+phdr->p_offset);
+                const int dynSize=phdr->p_memsz/sizeof(Elf32_Dyn);
+                for(int i=0;i<dynSize;i++,dyn++)
+                {
+                    switch(dyn->d_tag)
+                    {
+                        case DT_REL:
+                            hasRelocs=true;
+                            dtRel=dyn->d_un.d_ptr;
+                            break;
+                        case DT_RELSZ:
+                            hasRelocs=true;
+                            dtRelsz=dyn->d_un.d_val;
+                            break;
+                        case DT_MX_RAMSIZE:
+                            size=dyn->d_un.d_val;
+                            image=ProcessPool::instance()
+                                    .allocate(dyn->d_un.d_val);
+                        default:
+                            break;
+                    }
+                }
+                break;
+            }
+            default:
+                //Ignoring other segments
+                break;
+        }
+    }
+    const char *dataSegmentInFile=
+        reinterpret_cast<const char*>(base+dataSegment->p_offset);
+    char *dataSegmentInMem=reinterpret_cast<char*>(image);
+    memcpy(dataSegmentInMem,dataSegmentInFile,dataSegment->p_filesz);
+    dataSegmentInMem+=dataSegment->p_filesz;
+    memset(dataSegmentInMem,0,dataSegment->p_memsz-dataSegment->p_filesz);
+    if(hasRelocs)
+    {
+        const Elf32_Rel *rel=reinterpret_cast<const Elf32_Rel*>(base+dtRel);
+        const int relSize=dtRelsz/sizeof(Elf32_Rel);
+        const unsigned int base=reinterpret_cast<unsigned int>(image);
+        DBG("Relocations -- start (process RAM image @ 0x%x)\n",base);
+        for(int i=0;i<relSize;i++,rel++)
+        {
+            unsigned int offset=(rel->r_offset-DATA_START)/4;
+            switch(ELF32_R_TYPE(rel->r_info))
+            {
+                case R_ARM_RELATIVE:
+                    DBG("R_ARM_RELATIVE offset 0x%x from 0x%x to 0x%x\n",
+                        offset*4,image[offset],image[offset]+base-DATA_START);
+                    image[offset]+=base-DATA_START;
+                    break;
+                default:
+                    break;
+            }
+        }
+        DBG("Relocations -- end\n");
+    }
+}
+
+ProcessImage::~ProcessImage()
+{
+    if(image) ProcessPool::instance().deallocate(image);
+}
+
+} //namespace miosix
+
+#endif //WITH_PROCESSES
diff --git a/miosix/kernel/elf_program.h b/miosix/kernel/elf_program.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d5abed383da6451768805da6a2394bba02726f7
--- /dev/null
+++ b/miosix/kernel/elf_program.h
@@ -0,0 +1,178 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Terraneo Federico                               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+#ifndef ELF_PROGRAM_H
+#define	ELF_PROGRAM_H
+
+#include <utility>
+#include "elf_types.h"
+#include "config/miosix_settings.h"
+
+#ifdef WITH_PROCESSES
+
+namespace miosix {
+
+/**
+ * This class represents an elf file.
+ */
+class ElfProgram
+{
+public:
+    /**
+     * Constructor
+     * \param elf pointer to the elf file's content. Ownership of the data
+     * remains of the caller, that is, the pointer is not deleted by this
+     * class. This is done to allow passing a pointer directly to a location
+     * in the microcontroller's FLASH memory, in order to avoid copying the
+     * elf in RAM
+     * \param size size of the content of the elf file
+     */
+    ElfProgram(const unsigned int *elf, unsigned int size);
+    
+    /**
+     * \return the a pointer to the elf header
+     */
+    const Elf32_Ehdr *getElfHeader() const
+    {
+        return reinterpret_cast<const Elf32_Ehdr*>(elf);
+    }
+    
+    /**
+     * \return the already relocated value of the entry point 
+     */
+    unsigned int getEntryPoint() const
+    {
+        unsigned int base=reinterpret_cast<unsigned int>(elf);
+        return base+getElfHeader()->e_entry;
+    }
+    
+    /**
+     * \return an array of struct Elf32_Phdr
+     */
+    const Elf32_Phdr *getProgramHeaderTable() const
+    {
+        unsigned int base=reinterpret_cast<unsigned int>(elf);
+        return reinterpret_cast<const Elf32_Phdr*>(base+getElfHeader()->e_phoff);
+    }
+    
+    /**
+     * \return the number of entries in the program header table
+     */
+    int getNumOfProgramHeaderEntries() const
+    {
+        return getElfHeader()->e_phnum;
+    }
+    
+    /**
+     * \return a number representing the elf base address in memory
+     */
+    unsigned int getElfBase() const
+    {
+        return reinterpret_cast<unsigned int>(elf);
+    }
+    
+    /**
+     * \return the size of the elf file, as passed in the class' constructor
+     */
+    unsigned int getElfSize() const
+    {
+        return size;
+    }
+    
+private:
+    /**
+     * \param size elf file size
+     * \return false if the file is not valid
+     * \throws runtime_error for selected specific types of errors 
+     */
+    bool validateHeader();
+    
+    /**
+     * \param dynamic pointer to dynamic segment
+     * \param size elf file size
+     * \param dataSegmentSize size of data segment in memory
+     * \return false if the dynamic segment is not valid
+     * \throws runtime_error for selected specific types of errors 
+     */
+    bool validateDynamicSegment(const Elf32_Phdr *dynamic,
+            unsigned int dataSegmentSize);
+    
+    const unsigned int * const elf; ///<Pointer to the content of the elf file
+    unsigned int size; ///< Size of the elf file
+};
+
+/**
+ * This class represent the RAM image of a process.
+ */
+class ProcessImage
+{
+public:
+    /**
+     * Constructor, creates an empty process image.
+     */
+    ProcessImage() : image(0), size(0) {}
+    
+    /**
+     * Starting from the content of the elf program, create an image in RAM of
+     * the process, including copying .data, zeroing .bss and performing
+     * relocations
+     */
+    void load(const ElfProgram& program);
+    
+    /**
+     * \return a pointer to the base of the program image
+     */
+    unsigned int *getProcessBasePointer() const { return image; }
+    
+    /**
+     * \return the size of the process image, or zero if it is not valid 
+     */
+    unsigned int getProcessImageSize() const { return size; }
+    
+    /**
+     * \return true if this is a valid process image 
+     */
+    bool isValid() const { return image!=0; }
+    
+    /**
+     * Destructor. Deletes the process image memory.
+     */
+    ~ProcessImage();
+    
+private:
+    ProcessImage(const ProcessImage&);
+    ProcessImage& operator= (const ProcessImage&);
+    
+    unsigned int *image; //Pointer to the process image in RAM
+    unsigned int size;   //Size of the process image
+};
+
+} //namespace miosix
+
+#endif //WITH_PROCESSES
+
+#endif //ELF_PROGRAM_H
diff --git a/miosix/kernel/elf_types.h b/miosix/kernel/elf_types.h
new file mode 100644
index 0000000000000000000000000000000000000000..a4ef6e2d8868f70e8cc1e09be5fae600e7d907f3
--- /dev/null
+++ b/miosix/kernel/elf_types.h
@@ -0,0 +1,179 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Luigi Rucco and Terraneo Federico               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+#ifndef ELF_TYPES_H
+#define	ELF_TYPES_H
+
+#include <inttypes.h>
+#include "config/miosix_settings.h"
+
+#ifdef WITH_PROCESSES
+
+namespace miosix {
+
+// elf-specific types
+typedef uint32_t Elf32_Word;
+typedef int32_t  Elf32_Sword;
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Off;
+typedef uint32_t Elf32_Addr;
+
+// Size of e_ident in the elf header
+const int EI_NIDENT=16;
+
+/*
+ * Elf header
+ */
+struct Elf32_Ehdr
+{
+    unsigned char e_ident[EI_NIDENT]; // Ident bytes
+    Elf32_Half e_type;                // File type, any of the ET_* constants
+    Elf32_Half e_machine;             // Target machine
+    Elf32_Word e_version;             // File version
+    Elf32_Addr e_entry;               // Start address
+    Elf32_Off e_phoff;                // Phdr file offset
+    Elf32_Off e_shoff;                // Shdr file offset
+    Elf32_Word e_flags;               // File flags
+    Elf32_Half e_ehsize;              // Sizeof ehdr
+    Elf32_Half e_phentsize;           // Sizeof phdr
+    Elf32_Half e_phnum;               // Number phdrs
+    Elf32_Half e_shentsize;           // Sizeof shdr
+    Elf32_Half e_shnum;               // Number shdrs
+    Elf32_Half e_shstrndx;            // Shdr string index
+} __attribute__((packed));
+
+// Values for e_type
+const Elf32_Half ET_NONE = 0; // Unknown type
+const Elf32_Half ET_REL  = 1; // Relocatable
+const Elf32_Half ET_EXEC = 2; // Executable
+const Elf32_Half ET_DYN  = 3; // Shared object
+const Elf32_Half ET_CORE = 4; // Core file
+
+// Values for e_version
+const Elf32_Word EV_CURRENT = 1;
+
+// Values for e_machine
+const Elf32_Half EM_ARM  = 0x28;
+
+// Values for e_flags
+const Elf32_Word EF_ARM_EABI_MASK = 0x05000000;
+const Elf32_Word EF_HAS_ENTRY_POINT = 2;
+
+/*
+ * Elf program header
+ */
+struct Elf32_Phdr
+{
+    Elf32_Word p_type;   // Program header type, any of the PH_* constants
+    Elf32_Off  p_offset; // Segment start offset in file
+    Elf32_Addr p_vaddr;  // Segment virtual address
+    Elf32_Addr p_paddr;  // Segment physical address
+    Elf32_Word p_filesz; // Segment size in file
+    Elf32_Word p_memsz;  // Segment size in memory
+    Elf32_Word p_flags;  // Segment flasgs, any of the PF_* constants
+    Elf32_Word p_align;  // Segment alignment requirements
+} __attribute__((packed));
+
+// Values for p_type
+const Elf32_Word PT_NULL    = 0; // Unused array entry
+const Elf32_Word PT_LOAD    = 1; // Loadable segment
+const Elf32_Word PT_DYNAMIC = 2; // Segment is the dynamic section
+const Elf32_Word PT_INTERP  = 3; // Shared library interpreter
+const Elf32_Word PT_NOTE    = 4; // Auxiliary information
+
+// Values for p_flags
+const Elf32_Word PF_X = 0x1; // Execute
+const Elf32_Word PF_W = 0x2; // Write
+const Elf32_Word PF_R = 0x4; // Read
+
+/*
+ * Entries of the DYNAMIC segment
+ */
+struct Elf32_Dyn
+{
+    Elf32_Sword d_tag;    // Type of entry
+    union {
+        Elf32_Word d_val; // Value of entry, if number
+        Elf32_Addr d_ptr; // Value of entry, if offset into the file
+    } d_un;
+} __attribute__((packed));
+
+// Values for d_tag
+const int DT_NULL         = 0;
+const int DT_NEEDED       = 1;
+const int DT_PLTRELSZ     = 2;
+const int DT_PLTGOT       = 3;
+const int DT_HASH         = 4;
+const int DT_STRTAB       = 5;
+const int DT_SYMTAB       = 6;
+const int DT_RELA         = 7;
+const int DT_RELASZ       = 8;
+const int DT_RELAENT      = 9;
+const int DT_STRSZ        = 10;
+const int DT_SYMENT       = 11;
+const int DT_INIT         = 12;
+const int DT_FINI         = 13;
+const int DT_SONAME       = 14;
+const int DT_RPATH        = 15;
+const int DT_SYMBOLIC     = 16;
+const int DT_REL          = 17;
+const int DT_RELSZ        = 18;
+const int DT_RELENT       = 19;
+const int DT_PLTREL       = 20;
+const int DT_DEBUG        = 21;
+const int DT_TEXTREL      = 22;
+const int DT_JMPREL       = 23;
+const int DT_BINDNOW      = 24;
+const int DT_MX_RAMSIZE   = 0x10000000; //Miosix specific, RAM size
+const int DT_MX_STACKSIZE = 0x10000001; //Miosix specific, STACK size
+const int DT_MX_ABI       = 0x736f694d; //Miosix specific, ABI version
+const unsigned int DV_MX_ABI_V0 = 0x00007869; //Miosix specific, ABI version 0
+
+/*
+ * Relocation entries
+ */
+struct Elf32_Rel
+{
+    Elf32_Addr r_offset;
+    Elf32_Word r_info;
+} __attribute__((packed));
+
+// To extract the two fields of r_info
+#define ELF32_R_SYM(i) ((i)>>8)
+#define ELF32_R_TYPE(i) ((unsigned char)(i))
+
+
+// Possible values for ELF32_R_TYPE(r_info)
+const unsigned char R_ARM_NONE     = 0;
+const unsigned char R_ARM_ABS32    = 2;
+const unsigned char R_ARM_RELATIVE = 23;
+
+} //namespace miosix
+
+#endif //WITH_PROCESSES
+
+#endif //ELF_TYPES_H
diff --git a/miosix/kernel/kernel.cpp b/miosix/kernel/kernel.cpp
index 85363d08f1df5db8ee6ed15fe961487893e84ecd..eb041051d34966e8cce8e6e3fe6c60b0fb7f9bdb 100644
--- a/miosix/kernel/kernel.cpp
+++ b/miosix/kernel/kernel.cpp
@@ -34,6 +34,7 @@
 #include "arch_settings.h"
 #include "sync.h"
 #include "stage_2_boot.h"
+#include "process.h"
 #include "kernel/scheduler/scheduler.h"
 #include <stdexcept>
 #include <algorithm>
@@ -594,6 +595,36 @@ Thread *Thread::doCreate(void*(*startfunc)(void*) , unsigned int stacksize,
     return thread;
 }
 
+#ifdef WITH_PROCESSES
+
+void Thread::IRQhandleSvc(unsigned int svcNumber)
+{
+    if(cur->proc==0) errorHandler(UNEXPECTED);
+    if(svcNumber==1)
+    {
+        const_cast<Thread*>(cur)->flags.IRQsetUserspace(true);
+        ::ctxsave=cur->userCtxsave;
+        cur->proc->mpu.IRQenable();
+    } else {
+        const_cast<Thread*>(cur)->flags.IRQsetUserspace(false);
+        ::ctxsave=cur->ctxsave;
+        miosix_private::MPUConfiguration::IRQdisable();
+    }
+}
+
+bool Thread::IRQreportFault(const miosix_private::FaultData& fault)
+{
+    if(cur->proc==0 || const_cast<Thread*>(cur)->flags.isInUserspace()==false)
+        return false;
+    cur->proc->fault=fault;
+    const_cast<Thread*>(cur)->flags.IRQsetUserspace(false);
+    ::ctxsave=cur->ctxsave;
+    miosix_private::MPUConfiguration::IRQdisable();
+    return true;
+}
+
+#endif //WITH_PROCESSES
+
 void Thread::threadLauncher(void *(*threadfunc)(void*), void *argv)
 {
     void *result=0;
@@ -639,7 +670,88 @@ void Thread::threadLauncher(void *(*threadfunc)(void*), void *argv)
     Thread::yield();//Since the thread is now deleted, yield immediately.
     //Will never reach here
     errorHandler(UNEXPECTED);
+}
+
+#ifdef WITH_PROCESSES
+
+miosix_private::SyscallParameters Thread::switchToUserspace()
+{
+    miosix_private::portableSwitchToUserspace();
+    miosix_private::SyscallParameters result(cur->userCtxsave);
+    return result;
+}
+
+Thread *Thread::createUserspace(void *(*startfunc)(void *), void *argv,
+                    unsigned short options, Process *proc)
+{   
+    //Allocate memory for the thread, return if fail
+    unsigned int *base=static_cast<unsigned int*>(malloc(sizeof(Thread)+
+            SYSTEM_MODE_PROCESS_STACK_SIZE+WATERMARK_LEN+CTXSAVE_ON_STACK));
+    if(base==NULL)
+    {
+        errorHandler(OUT_OF_MEMORY);
+        return NULL;//Error
+    }
+    //At the top of thread memory allocate the Thread class with placement new
+    void *threadClass=base+((SYSTEM_MODE_PROCESS_STACK_SIZE+WATERMARK_LEN+
+            CTXSAVE_ON_STACK)/sizeof(unsigned int));
+    Thread *thread=new (threadClass) Thread(base,SYSTEM_MODE_PROCESS_STACK_SIZE,false);
+    try {
+        thread->userCtxsave=new unsigned int[CTXSAVE_SIZE];
+    } catch(std::bad_alloc&)
+    {
+        thread->~Thread();
+        free(base); //Delete ALL thread memory
+        errorHandler(OUT_OF_MEMORY);
+        return NULL;//Error
+    }
+
+    //Fill watermark and stack
+    memset(base, WATERMARK_FILL, WATERMARK_LEN);
+    base+=WATERMARK_LEN/sizeof(unsigned int);
+    memset(base, STACK_FILL, SYSTEM_MODE_PROCESS_STACK_SIZE);
+
+    //On some architectures some registers are saved on the stack, therefore
+    //initCtxsave *must* be called after filling the stack.
+    miosix_private::initCtxsave(thread->ctxsave,startfunc,
+            reinterpret_cast<unsigned int*>(thread),argv);
     
+    thread->proc=proc;
+    if((options & JOINABLE)==0) thread->flags.IRQsetDetached();
+    thread->flags.IRQsetWait(true); //Thread is not yet ready
+    
+    //Add thread to thread list
+    {
+        //Handling the list of threads, critical section is required
+        PauseKernelLock lock;
+        if(Scheduler::PKaddThread(thread,MAIN_PRIORITY)==false)
+        {
+            //Reached limit on number of threads
+            base=thread->watermark;
+            thread->~Thread();
+            free(base); //Delete ALL thread memory
+            return NULL;
+        }
+    }
+
+    return thread;
+}
+
+void Thread::setupUserspaceContext(unsigned int entry, unsigned int *gotBase,
+    unsigned int ramImageSize)
+{
+    void *(*startfunc)(void*)=reinterpret_cast<void *(*)(void*)>(entry);
+    unsigned int *ep=gotBase+ramImageSize/4;
+    miosix_private::initCtxsave(cur->userCtxsave,startfunc,ep,0,gotBase);
+}
+
+#endif //WITH_PROCESSES
+
+Thread::~Thread()
+{
+    #ifdef WITH_PROCESSES
+    if(userCtxsave) delete[] userCtxsave;
+    #endif //WITH_PROCESSES
 }
 
 //
diff --git a/miosix/kernel/kernel.h b/miosix/kernel/kernel.h
index 51045123e5c3fb15416fbe55c4ec5734c5eb03df..561cc7d4064f54457edd1a6a5e956409d7b27ba9 100644
--- a/miosix/kernel/kernel.h
+++ b/miosix/kernel/kernel.h
@@ -260,7 +260,7 @@ private:
  * kernel is paused will cause deadlock. Therefore, if possible, it is better to
  * use a Mutex instead of pausing the kernel<br>This function is safe to be
  * called even before the kernel is started. In this case it has no effect.
-*/
+ */
 void pauseKernel();
 
 /**
@@ -393,6 +393,9 @@ struct SleepData;
 class MemoryProfiling;
 class Mutex;
 class ConditionVariable;
+#ifdef WITH_PROCESSES
+class Process;
+#endif //WITH_PROCESSES
 
 /**
  * This class represents a thread. It has methods for creating, deleting and
@@ -687,6 +690,27 @@ public:
      * \return the size of the stack of the current thread.
      */
     static const int getStackSize();
+    
+    #ifdef WITH_PROCESSES
+    
+    /**
+     * \internal
+     * Can only be called inside an IRQ, its use is to switch a thread between
+     * userspace/kernelspace and back to perform context switches
+     */
+    static void IRQhandleSvc(unsigned int svcNumber);
+    
+    /**
+     * \internal
+     * Can only be called inside an IRQ, its use is to report a fault so that
+     * in case the fault has occurred within a process while it was executing
+     * in userspace, the process can be terminated.
+     * \param fault data about the occurred fault
+     * \return true if the fault was caused by a process, false otherwise.
+     */
+    static bool IRQreportFault(const miosix_private::FaultData& fault);
+    
+    #endif //WITH_PROCESSES
 	
 private:
     //Unwanted methods
@@ -699,45 +723,45 @@ private:
         /**
          * Constructor, sets flags to default.
          */
-        ThreadFlags(): flags(0) {}
+        ThreadFlags() : flags(0) {}
 
         /**
          * Set the wait flag of the thread.
-         * Can only be called with interrupts enabled or within an interrupt.
+         * Can only be called with interrupts disabled or within an interrupt.
          * \param waiting if true the flag will be set, otherwise cleared
          */
         void IRQsetWait(bool waiting);
 
         /**
          * Set the wait_join flag of the thread.
-         * Can only be called with interrupts enabled or within an interrupt.
+         * Can only be called with interrupts disabled or within an interrupt.
          * \param waiting if true the flag will be set, otherwise cleared
          */
         void IRQsetJoinWait(bool waiting);
 
         /**
          * Set wait_cond flag of the thread.
-         * Can only be called with interrupts enabled or within an interrupt.
+         * Can only be called with interrupts disabled or within an interrupt.
          * \param waiting if true the flag will be set, otherwise cleared
          */
         void IRQsetCondWait(bool waiting);
 
         /**
          * Set the sleep flag of the thread.
-         * Can only be called with interrupts enabled or within an interrupt.
+         * Can only be called with interrupts disabled or within an interrupt.
          * \param sleeping if true the flag will be set, otherwise cleared
          */
         void IRQsetSleep(bool sleeping);
 
         /**
          * Set the deleted flag of the thread. This flag can't be cleared.
-         * Can only be called with interrupts enabled or within an interrupt.
+         * Can only be called with interrupts disabled or within an interrupt.
          */
         void IRQsetDeleted();
 
         /**
          * Set the sleep flag of the thread. This flag can't be cleared.
-         * Can only be called with interrupts enabled or within an interrupt.
+         * Can only be called with interrupts disabled or within an interrupt.
          */
         void IRQsetDeleting()
         {
@@ -746,12 +770,22 @@ private:
 
         /**
          * Set the detached flag. This flag can't be cleared.
-         * Can only be called with interrupts enabled or within an interrupt.
+         * Can only be called with interrupts disabled or within an interrupt.
          */
         void IRQsetDetached()
         {
             flags |= DETACHED;
         }
+        
+        /**
+         * Set the userspace flag of the thread.
+         * Can only be called with interrupts disabled or within an interrupt.
+         * \param sleeping if true the flag will be set, otherwise cleared
+         */
+        void IRQsetUserspace(bool userspace)
+        {
+            if(userspace) flags |= USERSPACE; else flags &= ~USERSPACE;
+        }
 
         /**
          * \return true if the wait flag is set
@@ -798,6 +832,12 @@ private:
          * \return true if the thread is waiting on a condition variable
          */
         bool isWaitingCond() const { return flags & WAIT_COND; }
+        
+        /**
+         * \return true if the thread is running unprivileged inside a process.
+         * Only threads with proc!=null can run in userspace 
+         */
+        bool isInUserspace() const { return flags & USERSPACE; }
 
     private:
         ///\internal Thread is in the wait status. A call to wakeup will change
@@ -823,9 +863,47 @@ private:
 
         ///\internal Thread is waiting on a condition variable
         static const unsigned int WAIT_COND=1<<6;
+        
+        ///\internal Thread is running in userspace
+        static const unsigned int USERSPACE=1<<7;
 
         unsigned short flags;///<\internal flags are stored here
     };
+    
+    #ifdef WITH_PROCESSES
+
+    /**
+     * \internal
+     * Causes a thread belonging to a process to switch to userspace, and
+     * execute userspace code. This function returns when the process performs
+     * a syscall or faults.
+     * \return the syscall parameters used to serve the system call.
+     */
+    static miosix_private::SyscallParameters switchToUserspace();
+
+    /**
+     * Create a thread to be used inside a process. The thread is created in
+     * WAIT status, a wakeup() on it is required to actually start it.
+     * \param startfunc entry point
+     * \param argv parameter to be passed to the entry point
+     * \param options thread options
+     * \param proc process to which this thread belongs
+     */
+    static Thread *createUserspace(void *(*startfunc)(void *),
+        void *argv, unsigned short options, Process *proc);
+    
+    /**
+     * Setup the userspace context of the thread, so that it can be later
+     * switched to userspace. Must be called only once for each thread instance
+     * \param entry userspace entry point
+     * \param gotBase base address of the GOT, also corresponding to the start
+     * of the RAM image of the process
+     * \param ramImageSize size of the process ram image
+     */
+    static void setupUserspaceContext(unsigned int entry, unsigned int *gotBase,
+        unsigned int ramImageSize);
+    
+    #endif //WITH_PROCESSES
 
     /**
      * Constructor, initializes thread data.
@@ -839,12 +917,16 @@ private:
         cReent(defaultReent), cppReent()
     {
         joinData.waitingForJoin=NULL;
+        #ifdef WITH_PROCESSES
+        proc=0;
+        userCtxsave=0;
+        #endif //WITH_PROCESSES
     }
 
     /**
-     * Destructor, does nothing.
+     * Destructor
      */
-    ~Thread() {}
+    ~Thread();
     
     /**
      * Helper function to initialize a Thread
@@ -897,6 +979,14 @@ private:
     /// Per-thread instance of data to make the C and C++ libraries thread safe.
     CReentrancyData  cReent;
     CppReentrancyData cppReent;
+    #ifdef WITH_PROCESSES
+    ///Process to which this thread belongs. Null if it is a kernel thread.
+    Process *proc;
+    ///Pointer to the set of saved registers for when the thread is running in
+    ///user mode. For kernel threads (i.e, threads where proc==null) this
+    ///pointer is null
+    unsigned int *userCtxsave;
+    #endif //WITH_PROCESSES
     
     //friend functions
     //Needs access to watermark, ctxsave
@@ -932,6 +1022,10 @@ private:
     friend class CReentrancyAccessor;
     //Needs access to cppReent
     friend class CppReentrancyAccessor;
+    #ifdef WITH_PROCESSES
+    //Needs PKcreateUserspace(), setupUserspaceContext(), switchToUserspace()
+    friend class Process;
+    #endif //WITH_PROCESSES
 };
 
 /**
diff --git a/miosix/kernel/process.cpp b/miosix/kernel/process.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..edbaef3ff7c1945389d2691cc07b72416a429a7b
--- /dev/null
+++ b/miosix/kernel/process.cpp
@@ -0,0 +1,488 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Terraneo Federico                               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/
+
+#include <stdexcept>
+#include <memory>
+#include <cstdio>
+#include <cstring>
+#include <algorithm>
+#include <sys/wait.h>
+#include <signal.h>
+#include <limits.h>
+
+#include "sync.h"
+#include "process_pool.h"
+#include "process.h"
+#include "SystemMap.h"
+
+using namespace std;
+
+#ifdef WITH_PROCESSES
+
+/*
+ * List of implemented supervisor calls
+ * ------------------------------------
+ * 
+ * 0 : Yield. Can be called both by kernel threads and process threads both in
+ *     userspace and kernelspace mode. It causes the scheduler to switch to
+ *     another thread. It is the only SVC that is available also when processes
+ *     are disabled in miosix_config.h. No parameters, no return value.
+ * 1 : Back to userspace. It is used by process threads running in kernelspace
+ *     mode to return to userspace mode after completing a supervisor call.
+ *     If called by a process thread already in userspace mode it does nothing.
+ *     Use of this SVC is by kernel threads is forbidden. No parameters, no
+ *     return value.
+ * 2 : Exit. Terminates the current process. One parameter, the exit code.
+ *     Never returns. Use of this SVC is by kernel threads is forbidden.
+ * 3 : Write. Writes to stdout or a file. Three parameters, file descriptor,
+ *     pointer to data to be written, size of data. Returns the number of
+ *     written data or -1 on error. Use of this SVC is by kernel threads is
+ *     forbidden.
+ * 4 : Read. Reads from stdin or a file. Three parameters, file descriptor,
+ *     pointer to data buffer, size of buffer. Returns the number of
+ *     read data or -1 on error. Use of this SVC is by kernel threads is
+ *     forbidden.
+ * 5 : Usleep. One parameter, number of microseconds to sleep. Returns 0 on
+ *     success, -1 on failure. Use of this SVC is by kernel threads isforbidden.
+ */
+
+namespace miosix {
+
+//
+// class Process
+//
+
+pid_t Process::create(const ElfProgram& program)
+{
+    auto_ptr<Process> proc(new Process(program));
+    {   
+        Lock<Mutex> l(procMutex);
+        proc->pid=getNewPid();
+        if(Thread::getCurrentThread()->proc!=0)
+        {
+            proc->ppid=Thread::getCurrentThread()->proc->pid;
+            Thread::getCurrentThread()->proc->childs.push_back(proc.get());
+        } else {
+            proc->ppid=0;
+            kernelChilds.push_back(proc.get());
+        }
+        processes[proc->pid]=proc.get();
+    }
+    Thread *thr=Thread::createUserspace(Process::start,0,Thread::DEFAULT,
+        proc.get());
+    if(thr==0)
+    {
+        Lock<Mutex> l(procMutex);
+        processes.erase(proc->pid);
+        if(Thread::getCurrentThread()->proc!=0)
+        {
+            Thread::getCurrentThread()->proc->childs.remove(proc.get());
+        } else kernelChilds.remove(proc.get());
+        throw runtime_error("Thread creation failed");
+    }
+    //Cannot throw bad_alloc due to the reserve in Process's constructor.
+    //This ensures we will never be in the uncomfortable situation where a
+    //thread has already been created but there's no memory to list it
+    //among the threads of a process
+    proc->threads.push_back(thr);
+    thr->wakeup(); //Actually start the thread, now that everything is set up
+    pid_t result=proc->pid;
+    proc.release(); //Do not delete the pointer
+    return result;
+}
+
+pid_t Process::getppid(pid_t proc)
+{
+    Lock<Mutex> l(procMutex);
+    map<pid_t,Process *>::iterator it=processes.find(proc);
+    if(it==processes.end()) return -1;
+    return it->second->ppid;
+}
+
+pid_t Process::waitpid(pid_t pid, int* exit, int options)
+{
+    Lock<Mutex> l(procMutex);
+    Process *self=Thread::getCurrentThread()->proc;
+    if(self==0)
+    {
+        //The wait is performed by the kernel
+        if(pid<=0)
+        {
+            //Wait for a generic child process
+            if(kernelZombies.empty() && (options & WNOHANG)) return 0;
+            while(kernelZombies.empty())
+            {
+                if(kernelChilds.empty()) return -1;
+                genericWaiting.wait(l);
+            }
+            Process *joined=kernelZombies.front();
+            kernelZombies.pop_front();
+            processes.erase(joined->pid);
+            if(joined->waitCount!=0) errorHandler(UNEXPECTED);
+            if(exit!=0) *exit=joined->exitCode;
+            pid_t result=joined->pid;
+            delete joined;
+            return result;
+        } else {
+            //Wait on a specific child process
+            map<pid_t,Process *>::iterator it=processes.find(pid);
+            if(it==processes.end() || it->second->ppid!=0) return -1;
+            Process *joined=it->second;
+            if(joined->zombie==false)
+            {
+                //Process hasn't terminated yet
+                if(options & WNOHANG) return 0;
+                joined->waitCount++;
+                joined->waiting.wait(l);
+                joined->waitCount--;
+                if(joined->waitCount<0 || joined->zombie==false)
+                    errorHandler(UNEXPECTED);
+            }
+            //If multiple threads call waitpid on the same child, the last
+            //gets the return value, the other -1
+            pid_t result=-1;
+            if(joined->waitCount==0)
+            {
+                if(exit!=0) *exit=joined->exitCode;
+                result=joined->pid;
+                kernelZombies.remove(joined);
+                processes.erase(joined->pid);
+                delete joined;
+            }
+            return result;
+        }
+    } else {
+        //The wait is performed by a process
+        if(pid<=0)
+        {
+            //Wait for a generic child process
+            if(self->zombies.empty() && (options & WNOHANG)) return 0;
+            while(self->zombies.empty())
+            {
+                if(self->childs.empty()) return -1;
+                genericWaiting.wait(l);
+            }
+            Process *joined=self->zombies.front();
+            self->zombies.pop_front();
+            processes.erase(joined->pid);
+            if(joined->waitCount!=0) errorHandler(UNEXPECTED);
+            if(exit!=0) *exit=joined->exitCode;
+            pid_t result=joined->pid;
+            delete joined;
+            return result;
+        } else {
+            //Wait on a specific child process
+            map<pid_t,Process *>::iterator it=processes.find(pid);
+            if(it==processes.end() || it->second->ppid!=self->pid
+                    || pid==self->pid) return -1;
+            Process *joined=it->second;
+            if(joined->zombie==false)
+            {
+                //Process hasn't terminated yet
+                if(options & WNOHANG) return 0;
+                joined->waitCount++;
+                joined->waiting.wait(l);
+                joined->waitCount--;
+                if(joined->waitCount<0 || joined->zombie==false)
+                    errorHandler(UNEXPECTED);
+            }
+            pid_t result=-1;
+            if(joined->waitCount==0)
+            {
+                result=joined->pid;
+                if(exit!=0) *exit=joined->exitCode;
+                self->zombies.remove(joined);
+                processes.erase(joined->pid);
+                delete joined;
+            }
+            return result;
+        }
+    }
+}
+
+Process::~Process()
+{
+    #ifdef __CODE_IN_XRAM
+    ProcessPool::instance().deallocate(loadedProgram);
+    #endif //__CODE_IN_XRAM
+	
+	//close alla opened files
+	for(set<int>::iterator it = mFiles.begin(); it != mFiles.end(); ++it)
+		close(*it);
+}
+
+Process::Process(const ElfProgram& program) : program(program), waitCount(0),
+        zombie(false)
+{
+    //This is required so that bad_alloc can never be thrown when the first
+    //thread of the process will be stored in this vector
+    threads.reserve(1);
+    //Done here so if not enough memory the new process is not even created
+    image.load(program);
+    unsigned int elfSize=program.getElfSize();
+    unsigned int roundedSize=elfSize;
+    //Allocatable blocks must be greater than ProcessPool::blockSize, and must
+    //be a power of two due to MPU limitations
+    if(elfSize<ProcessPool::blockSize) roundedSize=ProcessPool::blockSize;
+    else if(elfSize & (elfSize-1)) roundedSize=1<<ffs(elfSize);
+    #ifndef __CODE_IN_XRAM
+    //FIXME -- begin
+    //Till a flash file system that ensures proper alignment of the programs
+    //loaded in flash is implemented, make the whole flash visible as a big MPU
+    //region
+    extern unsigned char _end asm("_end");
+    unsigned int flashEnd=reinterpret_cast<unsigned int>(&_end);
+    if(flashEnd & (flashEnd-1)) flashEnd=1<<ffs(flashEnd);
+    mpu=miosix_private::MPUConfiguration(0,flashEnd,
+            image.getProcessBasePointer(),image.getProcessImageSize());
+//    mpu=miosix_private::MPUConfiguration(program.getElfBase(),roundedSize,
+//            image.getProcessBasePointer(),image.getProcessImageSize());
+    //FIXME -- end
+    #else //__CODE_IN_XRAM
+    loadedProgram=ProcessPool::instance().allocate(roundedSize);
+    memcpy(loadedProgram,reinterpret_cast<char*>(program.getElfBase()),elfSize);
+    mpu=miosix_private::MPUConfiguration(loadedProgram,roundedSize,
+            image.getProcessBasePointer(),image.getProcessImageSize());
+    #endif //__CODE_IN_XRAM
+}
+
+void *Process::start(void *argv)
+{
+    Process *proc=Thread::getCurrentThread()->proc;
+    if(proc==0) errorHandler(UNEXPECTED);
+    unsigned int entry=proc->program.getEntryPoint();
+    #ifdef __CODE_IN_XRAM
+    entry=entry-proc->program.getElfBase()+
+        reinterpret_cast<unsigned int>(proc->loadedProgram);
+    #endif //__CODE_IN_XRAM
+    Thread::setupUserspaceContext(entry,proc->image.getProcessBasePointer(),
+        proc->image.getProcessImageSize());
+    bool running=true;
+    do {
+        miosix_private::SyscallParameters sp=Thread::switchToUserspace();
+        if(proc->fault.faultHappened())
+        {
+            running=false;
+            proc->exitCode=SIGSEGV; //Segfault
+            #ifdef WITH_ERRLOG
+            iprintf("Process %d terminated due to a fault\n"
+                    "* Code base address was 0x%x\n"
+                    "* Data base address was %p\n",proc->pid,
+                    #ifndef __CODE_IN_XRAM
+                    proc->program.getElfBase(),
+                    #else //__CODE_IN_XRAM
+                    reinterpret_cast<unsigned int>(proc->loadedProgram),
+                    #endif //__CODE_IN_XRAM
+                    proc->image.getProcessBasePointer());
+            proc->mpu.dumpConfiguration();
+            proc->fault.print();
+            #endif //WITH_ERRLOG
+        } else {
+            switch(sp.getSyscallId())
+            {
+                case 2:
+                    running=false;
+                    proc->exitCode=(sp.getFirstParameter() & 0xff)<<8;
+                    break;
+                case 3:
+                    //FIXME: check that the pointer belongs to the process
+					
+					if((sp.getFirstParameter() >= 0 && sp.getFirstParameter() < 3) ||		//stdio
+						proc->mFiles.find(sp.getFirstParameter()) != proc->mFiles.end()){	//only on my files
+						
+						//check if pointer and pointer + size is within the mpu data region
+						if(!proc->mpu.within(sp.getSecondParameter()) ||
+						   !proc->mpu.within(sp.getSecondParameter() + sp.getThirdParameter())){
+							running = false;
+							proc->exitCode = SIGSYS;
+							break;
+						}
+						
+						sp.setReturnValue(write(sp.getFirstParameter(),
+												reinterpret_cast<const char*>(sp.getSecondParameter()),
+												sp.getThirdParameter()));
+					} else 
+						sp.setReturnValue(-1);
+					
+                    break;
+                case 4:					
+					if((sp.getFirstParameter() >= 0 && sp.getFirstParameter() < 3) ||		//stdio
+						proc->mFiles.find(sp.getFirstParameter())!= proc->mFiles.end()){	//only on my files
+                    
+						//check if pointer and pointer + size is within the mpu data region
+						if(!proc->mpu.within(sp.getSecondParameter()) ||
+						   !proc->mpu.within(sp.getSecondParameter() + sp.getThirdParameter())){
+							running = false;
+							proc->exitCode = SIGSYS;
+							break;
+						}
+							
+						sp.setReturnValue(read(sp.getFirstParameter(),
+											   reinterpret_cast<char*>(sp.getSecondParameter()),
+											   sp.getThirdParameter()));
+					} else
+						sp.setReturnValue(-1);
+					
+                    break;
+                case 5:
+					sp.setReturnValue(usleep(sp.getFirstParameter()));
+                    break;
+				#ifdef WITH_FILESYSTEM
+				case 6:
+					//open
+				{
+					unsigned int base = proc->mpu.getBaseDataAddress();
+					unsigned int size = proc->mpu.getDataSize();
+					
+					unsigned int maxLen = min(base + size - sp.getFirstParameter(), (unsigned int)PATH_MAX);
+					size_t filenameLen = strnlen(reinterpret_cast<const char*>(sp.getFirstParameter()), maxLen);
+					
+					if(!proc->mpu.within(sp.getFirstParameter()) ||
+					   !proc->mpu.within(sp.getFirstParameter() + filenameLen)){
+						
+						proc->mpu.dumpConfiguration();	
+						
+						running = false;
+						proc->exitCode = SIGSYS;
+						break;
+					}
+
+					int fd = open(reinterpret_cast<const char*>(sp.getFirstParameter()),	//filename
+								  sp.getSecondParameter(),									//flags
+								  sp.getThirdParameter());									//permission, used?
+					if (fd != -1)
+						proc->mFiles.insert(fd);
+						
+					sp.setReturnValue(fd);
+				}
+                    break;
+				case 7:
+					//close
+					if(proc->mFiles.find(sp.getFirstParameter()) != proc->mFiles.end()){
+						int ret = close(sp.getFirstParameter());
+						
+						if(ret == 0)
+							proc->mFiles.erase(sp.getFirstParameter());
+						
+						sp.setReturnValue(ret);
+					} else 
+						sp.setReturnValue(-1);
+					break;
+				case 8:
+					//seek
+					if(proc->mFiles.find(sp.getFirstParameter()) != proc->mFiles.end())
+						sp.setReturnValue(Filesystem::instance().lseekFile(sp.getFirstParameter(),
+																		   sp.getSecondParameter(),
+																		   sp.getThirdParameter()));
+					else
+						sp.setReturnValue(-1);
+					
+					break;
+				#endif //WITH_FILESYSTEM
+				case 9:
+					//system
+				{				
+					std::pair<const unsigned int*, unsigned int> res = SystemMap::instance().getElfProgram(reinterpret_cast<const char*>(sp.getFirstParameter()));
+							
+					if(res.first == 0 || res.second == 0){
+						iprintf("Program not found.\n");
+						sp.setReturnValue(-1);
+						break;
+					}
+								
+					ElfProgram program(res.first, res.second);
+					int ret = 0;
+					
+					pid_t child = Process::create(program);
+					Process::waitpid(child, &ret, 0);
+					
+					sp.setReturnValue(WEXITSTATUS(ret));
+				}
+					break;
+                default:
+                    running=false;
+                    proc->exitCode=SIGSYS; //Bad syscall
+                    #ifdef WITH_ERRLOG
+                    iprintf("Unexpected syscall number %d\n",sp.getSyscallId());
+                    #endif //WITH_ERRLOG
+                    break;
+            }
+        }
+        if(Thread::testTerminate()) running=false;
+    } while(running);
+    {
+        Lock<Mutex> l(procMutex);
+        proc->zombie=true;
+        list<Process*>::iterator it;
+        for(it=proc->childs.begin();it!=proc->childs.end();++it) (*it)->ppid=0;
+        for(it=proc->zombies.begin();it!=proc->zombies.end();++it) (*it)->ppid=0;
+        kernelChilds.splice(kernelChilds.begin(),proc->childs);
+        kernelZombies.splice(kernelZombies.begin(),proc->zombies);
+        if(proc->ppid!=0)
+        {
+            map<pid_t,Process *>::iterator it=processes.find(proc->ppid);
+            if(it==processes.end()) errorHandler(UNEXPECTED);
+            it->second->childs.remove(proc);
+            if(proc->waitCount>0) proc->waiting.broadcast();
+            else {
+                it->second->zombies.push_back(proc);
+                genericWaiting.broadcast();
+            }
+        } else {
+            kernelChilds.remove(proc);
+            if(proc->waitCount>0) proc->waiting.broadcast();
+            else {
+                kernelZombies.push_back(proc);
+                genericWaiting.broadcast();
+            }
+        }
+    }
+    return 0;
+}
+
+pid_t Process::getNewPid()
+{
+    for(;;pidCounter++)
+    {
+        if(pidCounter<0) pidCounter=1;
+        if(pidCounter==0) continue; //Zero is not a valid pid
+        map<pid_t,Process*>::iterator it=processes.find(pidCounter);
+        if(it!=processes.end()) continue; //Pid number already used
+        return pidCounter++;
+    }
+}
+
+map<pid_t,Process*> Process::processes;
+std::list<Process *> Process::kernelChilds;
+std::list<Process *> Process::kernelZombies;
+pid_t Process::pidCounter=1;
+Mutex Process::procMutex;
+ConditionVariable Process::genericWaiting;
+    
+} //namespace miosix
+
+#endif //WITH_PROCESSES
diff --git a/miosix/kernel/process.h b/miosix/kernel/process.h
new file mode 100644
index 0000000000000000000000000000000000000000..466f0be9b1c99bb672078ba64d85f748e9f6c517
--- /dev/null
+++ b/miosix/kernel/process.h
@@ -0,0 +1,166 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Terraneo Federico                               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/ 
+
+#ifndef PROCESS_H
+#define	PROCESS_H
+
+#include <vector>
+#include <map>
+#include <list>
+#include <set>
+#include <sys/types.h>
+#include "kernel.h"
+#include "sync.h"
+#include "elf_program.h"
+#include "config/miosix_settings.h"
+
+#ifdef WITH_PROCESSES
+
+namespace miosix {
+
+/**
+ * Process class, allows to create and handle processes
+ */
+class Process
+{
+public:
+    /**
+     * Create a new process
+     * \param program Program that the process will execute
+     * \return the pid of the newly created process
+     * \throws std::exception or a subclass in case of errors, including
+     * not emough memory to spawn the process
+     */
+    static pid_t create(const ElfProgram& program);
+    
+    /**
+     * Given a process, returns the pid of its parent.
+     * \param proc the pid of a process
+     * \return the pid of the parent process, or zero if the process was created
+     * by the kernel directly, or -1 if proc is not a valid process
+     */
+    static pid_t getppid(pid_t proc);
+    
+    /**
+     * Wait for child process termination
+     * \param exit the process exit code will be returned here, if the pointer
+     * is not null
+     * \return the pid of the terminated process, or -1 in case of errors
+     */
+    static pid_t wait(int *exit) { return waitpid(-1,exit,0); }
+    
+    /**
+     * Wait for a specific child process to terminate
+     * \param pid pid of the process, or -1 to wait for any child process
+     * \param exit the process exit code will be returned here, if the pointer
+     * is not null
+     * \param options only 0 and WNOHANG are supported
+     * \return the pid of the terminated process, or -1 in case of errors. In
+     * case WNOHANG  is specified and the specified process has not terminated,
+     * 0 is returned
+     */
+    static pid_t waitpid(pid_t pid, int *exit, int options);
+    
+    /**
+     * Destructor
+     */
+    ~Process();
+    
+private:
+    Process(const Process&);
+    Process& operator= (const Process&);
+    
+    /**
+     * Constructor
+     * \param program program that will be executed by the process
+     */
+    Process(const ElfProgram& program);
+    
+    /**
+     * Contains the process' main loop. 
+     * \param argv ignored parameter
+     * \return null
+     */
+    static void *start(void *argv);
+    
+    /**
+     * \return an unique pid that is not zero and is not already in use in the
+     * system, used to assign a pid to a new process.<br>
+     */
+    static pid_t getNewPid();
+    
+    ElfProgram program; ///<The program that is running inside the process
+    #ifdef __CODE_IN_XRAM
+    /// When __CODE_IN_XRAM is defined, the programs are loaded in the process
+    /// pool so the memory is aligned and the MPU works
+    unsigned int *loadedProgram;
+    #endif //__CODE_IN_XRAM
+    ProcessImage image; ///<The RAM image of a process
+    miosix_private::FaultData fault; ///< Contains information about faults
+    miosix_private::MPUConfiguration mpu; ///<Memory protection data
+    
+    std::vector<Thread *> threads; ///<Threads that belong to the process
+    std::list<Process *> childs;   ///<Living child processes are stored here
+    std::list<Process *> zombies;  ///<Dead child processes are stored here
+    std::set<int> mFiles;		   ///<Files openend by this process
+    pid_t pid;  ///<The pid of this process
+    pid_t ppid; ///<The parent pid of this process
+    ///Contains the count of active wait calls which specifically requested
+    ///to wait on this process
+    int waitCount;
+    ///Active wait calls which specifically requested to wait on this process
+    ///wait on this condition variable
+    ConditionVariable waiting;
+    bool zombie; ///< True for terminated not yet joined processes
+    short int exitCode; ///< Contains the exit code
+    
+    ///Maps the pid to the Process instance. Includes zombie processes
+    static std::map<pid_t,Process *> processes;
+    static std::list<Process *> kernelChilds;
+    static std::list<Process *> kernelZombies;
+    ///Used to assign a new pid to a process
+    static pid_t pidCounter;
+    ///Uset to guard access to processes and pidCounter
+    static Mutex procMutex;
+    ///Used to wait on process termination
+    static ConditionVariable genericWaiting;
+    
+    //Needs access to fault,mpu
+    friend class Thread;
+    //Needs access to mpu
+    friend class PriorityScheduler;
+    //Needs access to mpu
+    friend class ControlScheduler;
+    //Needs access to mpu
+    friend class EDFScheduler;
+};
+
+} //namespace miosix
+
+#endif //WITH_PROCESSES
+
+#endif //PROCESS_H
diff --git a/miosix/kernel/process_pool.cpp b/miosix/kernel/process_pool.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a3401f43f9e5d4cbb7ad86fb5fb6cad315b53de3
--- /dev/null
+++ b/miosix/kernel/process_pool.cpp
@@ -0,0 +1,158 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Terraneo Federico and Luigi Rucco               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/ 
+
+#include "process_pool.h"
+#include <stdexcept>
+#include <cstring>
+
+using namespace std;
+
+#ifdef WITH_PROCESSES
+
+namespace miosix {
+
+ProcessPool& ProcessPool::instance()
+{
+    #ifndef TEST_ALLOC
+    //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(&_process_pool_start,
+        reinterpret_cast<unsigned int>(&_process_pool_end)-
+        reinterpret_cast<unsigned int>(&_process_pool_start));
+    return pool;
+    #else //TEST_ALLOC
+    static ProcessPool pool(reinterpret_cast<unsigned int*>(0x20008000),96*1024);
+    return pool;
+    #endif //TEST_ALLOC
+}
+    
+unsigned int *ProcessPool::allocate(unsigned int size)
+{
+    #ifndef TEST_ALLOC
+    miosix::Lock<miosix::FastMutex> l(mutex);
+    #endif //TEST_ALLOC
+    //If size is not a power of two, or too big or small
+    if((size & (size - 1)) || size>poolSize || size<blockSize)
+            throw runtime_error("");
+    
+    unsigned int offset=0;
+    if(reinterpret_cast<unsigned int>(poolBase) % size)
+        offset=size-(reinterpret_cast<unsigned int>(poolBase) % size);
+    unsigned int startBit=offset/blockSize;
+    unsigned int sizeBit=size/blockSize;
+
+    for(unsigned int i=startBit;i<=poolSize/blockSize;i+=sizeBit)
+    {
+        bool notEmpty=false;
+        for(unsigned int j=0;j<sizeBit;j++)
+        {
+            if(testBit(i+j)==0) continue;
+            notEmpty=true;
+            break;
+        }
+        if(notEmpty) continue;
+        
+        for(unsigned int j=0;j<sizeBit;j++) setBit(i+j);
+        unsigned int *result=poolBase+i*blockSize/sizeof(unsigned int);
+        allocatedBlocks[result]=size;
+        return result;
+    }
+    throw bad_alloc();
+}
+
+void ProcessPool::deallocate(unsigned int *ptr)
+{
+    #ifndef TEST_ALLOC
+    miosix::Lock<miosix::FastMutex> l(mutex);
+    #endif //TEST_ALLOC
+    map<unsigned int*, unsigned int>::iterator it= allocatedBlocks.find(ptr);
+    if(it==allocatedBlocks.end())throw runtime_error("");
+    unsigned int size =(it->second)/blockSize;
+    unsigned int firstBit=(reinterpret_cast<unsigned int>(ptr)-
+                           reinterpret_cast<unsigned int>(poolBase))/blockSize;
+    for(unsigned int i=firstBit;i<firstBit+size;i++) clearBit(i);
+    allocatedBlocks.erase(it);
+}
+
+ProcessPool::ProcessPool(unsigned int *poolBase, unsigned int poolSize)
+    : poolBase(poolBase), poolSize(poolSize)
+{
+    int numBytes=poolSize/blockSize/8;
+    bitmap=new unsigned int[numBytes/sizeof(unsigned int)];
+    memset(bitmap,0,numBytes);
+}
+
+ProcessPool::~ProcessPool()
+{
+    delete[] bitmap;
+}
+
+#ifdef TEST_ALLOC
+int main()
+{
+    ProcessPool& pool=ProcessPool::instance();
+    while(1)
+    {
+        cout<<"a<size(exponent)>|d<addr>"<<endl;
+        unsigned int param;
+        char op;
+        string line;
+        getline(cin,line);
+        stringstream ss(line);
+        ss>>op;
+        switch(op)
+        {
+            case 'a':
+                ss>>dec>>param;
+                try {
+                    pool.allocate(1<<param);
+                } catch(exception& e) {
+                    cout<<typeid(e).name();
+                }
+                pool.printAllocatedBlocks();
+                break;
+            case 'd':
+                ss>>hex>>param;
+                try {
+                    pool.deallocate(reinterpret_cast<unsigned int*>(param));
+                } catch(exception& e) {
+                    cout<<typeid(e).name();
+                }
+                pool.printAllocatedBlocks();
+                break;
+            default:
+                cout<<"Incorrect option"<<endl;
+                break;
+        }          
+    }
+}
+#endif //TEST_ALLOC
+
+} //namespace miosix
+
+#endif //WITH_PROCESSES
diff --git a/miosix/kernel/process_pool.h b/miosix/kernel/process_pool.h
new file mode 100644
index 0000000000000000000000000000000000000000..26f5d1561d303d3a5c5f568e14e81b426cfeaf37
--- /dev/null
+++ b/miosix/kernel/process_pool.h
@@ -0,0 +1,173 @@
+/***************************************************************************
+ *   Copyright (C) 2012 by Terraneo Federico and Luigi Rucco               *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   As a special exception, if other files instantiate templates or use   *
+ *   macros or inline functions from this file, or you compile this file   *
+ *   and link it with other works to produce a work based on this file,    *
+ *   this file does not by itself cause the resulting work to be covered   *
+ *   by the GNU General Public License. However the source code for this   *
+ *   file must still be made available in accordance with the GNU General  *
+ *   Public License. This exception does not invalidate any other reasons  *
+ *   why a work based on this file might be covered by the GNU General     *
+ *   Public License.                                                       *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, see <http://www.gnu.org/licenses/>   *
+ ***************************************************************************/ 
+
+#ifndef PROCESS_POOL
+#define PROCESS_POOL
+
+#include <map>
+
+#ifndef TEST_ALLOC
+#include <miosix.h>
+#else //TEST_ALLOC
+#include <iostream>
+#include <typeinfo>
+#include <sstream>
+#endif //TEST_ALLOC
+
+#ifdef WITH_PROCESSES
+
+namespace miosix {
+
+/**
+ * This class allows to handle a memory area reserved for the allocation of
+ * processes' images. This memory area is called process pool.
+ */
+class ProcessPool
+{
+public:
+    /**
+     * \return an instance of the process pool (singleton)
+     */
+    static ProcessPool& instance();
+    
+    /**
+     * Allocate memory inside the process pool.
+     * \param size size of the requested memory, must be a power of two,
+     * and be grater or equal to blockSize.
+     * \return a pointer to the allocated memory. Note that the pointer is
+     * size-aligned, so that for example if a 16KByte block is requested,
+     * the returned pointer is aligned on a 16KB boundary. This is so to
+     * allow using the MPU of the Cortex-M3.
+     * \throws runtime_error in case the requested allocation is invalid,
+     * or bad_alloc if out of memory
+     */
+    unsigned int *allocate(unsigned int size);
+    
+    /**
+     * Deallocate a memory block.
+     * \param ptr pointer to deallocate.
+     * \throws runtime_error if the pointer is invalid
+     */
+    void deallocate(unsigned int *ptr);
+    
+    #ifdef TEST_ALLOC
+    /**
+     * Print the state of the allocator, used for debugging
+     */
+    void printAllocatedBlocks()
+    {
+        using namespace std;
+        map<unsigned int*, unsigned int>::iterator it;
+        cout<<endl;
+        for(it=allocatedBlocks.begin();it!=allocatedBlocks.end();it++)
+            cout <<"block of size " << it->second
+                 << " allocated @ " << it->first<<endl;
+        
+        cout<<"Bitmap:"<<endl;
+        const int SHIFT = 8 * sizeof(unsigned int);
+        const unsigned int MASK = 1 << (SHIFT-1);
+        int bitarray[32];
+        for(int i=0; i<(poolSize/blockSize)/(sizeof(unsigned int)*8);i++)
+        {   
+            int value=bitmap[i];
+            for ( int j = 0; j < SHIFT; j++ ) 
+            {
+                bitarray[31-j]= ( value & MASK ? 1 : 0 );
+                value <<= 1;
+            }
+            for(int j=0;j<32;j++)
+                cout<<bitarray[j];
+            cout << endl;
+        }  
+    }
+    #endif //TEST_ALLOC
+    
+    ///This constant specifies the size of the minimum allocatable block,
+    ///in bits. So for example 10 is 1KB.
+    static const unsigned int blockBits=10;
+    ///This constant is the the size of the minimum allocatable block, in bytes.
+    static const unsigned int blockSize=1<<blockBits;
+    
+private:
+    ProcessPool(const ProcessPool&);
+    ProcessPool& operator= (const ProcessPool&);
+    
+    /**
+     * Constructor.
+     * \param poolBase address of the start of the process pool.
+     * \param poolSize size of the process pool. Must be a multiple of blockSize
+     */
+    ProcessPool(unsigned int *poolBase, unsigned int poolSize);
+    
+    /**
+     * Destructor
+     */
+    ~ProcessPool();
+    
+    /**
+     * \param bit bit to test, from 0 to poolSize/blockSize
+     * \return true if the bit is set
+     */
+    bool testBit(unsigned int bit)
+    {
+        return (bitmap[bit/(sizeof(unsigned int)*8)] &
+            1<<(bit % (sizeof(unsigned int)*8))) ? true : false;
+    }
+    
+    /**
+     * \param bit bit to set, from 0 to poolSize/blockSize
+     */
+    void setBit(unsigned int bit)
+    {
+        bitmap[(bit/(sizeof(unsigned int)*8))] |= 
+            1<<(bit % (sizeof(unsigned int)*8));
+    }
+    
+    /**
+     * \param bit bit to clear, from 0 to poolSize/blockSize
+     */
+    void clearBit(unsigned int bit)
+    {
+        bitmap[bit/(sizeof(unsigned int)*8)] &= 
+            ~(1<<(bit % (sizeof(unsigned int)*8)));
+    }
+    
+    unsigned int *bitmap;   ///< Pointer to the status of the allocator
+    unsigned int *poolBase; ///< Base address of the entire pool
+    unsigned int poolSize;  ///< Size of the pool, in bytes
+    ///Lists all allocated blocks, allows to retrieve their sizes
+    std::map<unsigned int*,unsigned int> allocatedBlocks;
+    #ifndef TEST_ALLOC
+    miosix::FastMutex mutex; ///< Mutex to guard concurrent access
+    #endif //TEST_ALLOC
+};
+
+} //namespace miosix
+
+#endif //WITH_PROCESSES
+
+#endif //PROCESS_POOL
diff --git a/miosix/kernel/scheduler/control/control_scheduler.cpp b/miosix/kernel/scheduler/control/control_scheduler.cpp
index 659c2dec791507ffa8da99e9a3715f1d0576b95b..3be4cd723afbe27ce96d7b2fafb1a57688aaf092 100644
--- a/miosix/kernel/scheduler/control/control_scheduler.cpp
+++ b/miosix/kernel/scheduler/control/control_scheduler.cpp
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2010, 2011 by Terraneo Federico                         *
+ *   Copyright (C) 2010, 2011, 2012 by Terraneo Federico                   *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -27,6 +27,7 @@
 
 #include "control_scheduler.h"
 #include "kernel/error.h"
+#include "kernel/process.h"
 #include <limits>
 
 using namespace std;
@@ -200,6 +201,9 @@ void ControlScheduler::IRQfindNextThread()
                 curInRound=0;
                 cur=idle;
                 ctxsave=cur->ctxsave;
+                #ifdef WITH_PROCESSES
+                miosix_private::MPUConfiguration::IRQdisable();
+                #endif
                 miosix_private::AuxiliaryTimer::IRQsetValue(bIdle);
                 return;
             }
@@ -213,7 +217,18 @@ void ControlScheduler::IRQfindNextThread()
         {
             //Found a READY thread, so run this one
             cur=curInRound;
+            #ifdef WITH_PROCESSES
+            if(const_cast<Thread*>(cur)->flags.isInUserspace()==false)
+            {
+                ctxsave=cur->ctxsave;
+                miosix_private::MPUConfiguration::IRQdisable();
+            } else {
+                ctxsave=cur->userCtxsave;
+                cur->proc->mpu.IRQenable();
+            }
+            #else //WITH_PROCESSES
             ctxsave=cur->ctxsave;
+            #endif //WITH_PROCESSES
             miosix_private::AuxiliaryTimer::IRQsetValue(
                     curInRound->schedData.bo/multFactor);
             return;
diff --git a/miosix/kernel/scheduler/edf/edf_scheduler.cpp b/miosix/kernel/scheduler/edf/edf_scheduler.cpp
index fa7ca01584d6dd095a9c716a612da5ae4dc77840..5eac0a0b159ab7527435b46ed421a7092979d833 100644
--- a/miosix/kernel/scheduler/edf/edf_scheduler.cpp
+++ b/miosix/kernel/scheduler/edf/edf_scheduler.cpp
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2010, 2011 by Terraneo Federico                         *
+ *   Copyright (C) 2010, 2011, 2012 by Terraneo Federico                   *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -27,6 +27,7 @@
 
 #include "edf_scheduler.h"
 #include "kernel/error.h"
+#include "kernel/process.h"
 #include <algorithm>
 
 using namespace std;
@@ -115,7 +116,18 @@ void EDFScheduler::IRQfindNextThread()
         if(walk->flags.isReady())
         {
             cur=walk;
+            #ifdef WITH_PROCESSES
+            if(const_cast<Thread*>(cur)->flags.isInUserspace()==false)
+            {
+                ctxsave=cur->ctxsave;
+                miosix_private::MPUConfiguration::IRQdisable();
+            } else {
+                ctxsave=cur->userCtxsave;
+                cur->proc->mpu.IRQenable();
+            }
+            #else //WITH_PROCESSES
             ctxsave=cur->ctxsave;
+            #endif //WITH_PROCESSES
             return;
         }
         walk=walk->schedData.next;
diff --git a/miosix/kernel/scheduler/priority/priority_scheduler.cpp b/miosix/kernel/scheduler/priority/priority_scheduler.cpp
index fe8845504a7cfee9e7e8959ee0fe79d873a4ee65..90c96295d107b68dcb16ad7283a459d66bc6b9e8 100644
--- a/miosix/kernel/scheduler/priority/priority_scheduler.cpp
+++ b/miosix/kernel/scheduler/priority/priority_scheduler.cpp
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2010 by Terraneo Federico                               *
+ *   Copyright (C) 2010, 2011, 2012 by Terraneo Federico                   *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -27,6 +27,7 @@
 
 #include "priority_scheduler.h"
 #include "kernel/error.h"
+#include "kernel/process.h"
 
 #ifdef SCHED_TYPE_PRIORITY
 
@@ -209,7 +210,18 @@ void PriorityScheduler::IRQfindNextThread()
             {
                 //Found a READY thread, so run this one
                 cur=temp;
+                #ifdef WITH_PROCESSES
+                if(const_cast<Thread*>(cur)->flags.isInUserspace()==false)
+                {
+                    ctxsave=cur->ctxsave;
+                    miosix_private::MPUConfiguration::IRQdisable();
+                } else {
+                    ctxsave=cur->userCtxsave;
+                    cur->proc->mpu.IRQenable();
+                }
+                #else //WITH_PROCESSES
                 ctxsave=temp->ctxsave;
+                #endif //WITH_PROCESSES
                 //Rotate to next thread so that next time the list is walked
                 //a different thread, if available, will be chosen first
                 thread_list[i]=temp;
@@ -221,6 +233,9 @@ void PriorityScheduler::IRQfindNextThread()
     //No thread found, run the idle thread
     cur=idle;
     ctxsave=idle->ctxsave;
+    #ifdef WITH_PROCESSES
+    miosix_private::MPUConfiguration::IRQdisable();
+    #endif //WITH_PROCESSES
 }
 
 Thread *PriorityScheduler::thread_list[PRIORITY_MAX]={0};
diff --git a/miosix/util/util.cpp b/miosix/util/util.cpp
index a67b6dd5c910e92bf261cc85e958fc4a3d24e6eb..dbf4f9cafc91348db4d0d8274eb0b950d79b21b4 100644
--- a/miosix/util/util.cpp
+++ b/miosix/util/util.cpp
@@ -75,23 +75,21 @@ unsigned int MemoryProfiling::getStackSize()
 
 unsigned int MemoryProfiling::getAbsoluteFreeStack()
 {
-    unsigned int count=0;
     const unsigned int *walk=miosix::Thread::getStackBottom();
-    for(;;)
+    const unsigned int stackSize=miosix::Thread::getStackSize();
+    unsigned int count=0;
+    while(count<stackSize && *walk==miosix::STACK_FILL)
     {
         //Count unused stack
-        if(*walk!=miosix::STACK_FILL)
-        {
-            //This takes in account CTXSAVE_ON_STACK. It might underestimate
-            //the absolute free stack (by a maximum of CTXSAVE_ON_STACK) but
-            //it will never overestimate it, which is important since this
-            //member function can be used to select stack sizes.
-            if(count<=CTXSAVE_ON_STACK) return 0;
-            return count-CTXSAVE_ON_STACK;
-        }
         walk++;
         count+=4;
     }
+    //This takes in account CTXSAVE_ON_STACK. It might underestimate
+    //the absolute free stack (by a maximum of CTXSAVE_ON_STACK) but
+    //it will never overestimate it, which is important since this
+    //member function can be used to select stack sizes.
+    if(count<=CTXSAVE_ON_STACK) return 0;
+    return count-CTXSAVE_ON_STACK;
 }
 
 unsigned int MemoryProfiling::getCurrentFreeStack()