Index: /soft/giet_vm/giet_libs/malloc.c
===================================================================
--- /soft/giet_vm/giet_libs/malloc.c	(revision 389)
+++ /soft/giet_vm/giet_libs/malloc.c	(revision 390)
@@ -78,6 +78,7 @@
     }
 
-    // compute alloc[] minimal array size
+    // compute size of block containin alloc[] array 
     alloc_size = heap_size / MIN_BLOCK_SIZE;
+    if ( alloc_size < MIN_BLOCK_SIZE) alloc_size = MIN_BLOCK_SIZE;
 
     // get index for the corresponding block
@@ -98,5 +99,5 @@
     unsigned int   base = heap_base;
     unsigned int*  ptr;
-    for ( index = heap_index-1 ; index > alloc_index ; index-- )
+    for ( index = heap_index-1 ; index >= alloc_index ; index-- )
     {
         heap[x][y].free[index] = base;
@@ -247,4 +248,7 @@
     }
 
+    // normalize size
+    if ( size < MIN_BLOCK_SIZE ) size = MIN_BLOCK_SIZE;
+
     // compute requested_index for the free[] array
     unsigned int requested_index = GET_SIZE_INDEX( size );
@@ -258,8 +262,11 @@
                                    requested_index );
 
-    // update the alloc[] array
-    unsigned offset = (base - heap[x][y].heap_base) / MIN_BLOCK_SIZE;
-    unsigned char* ptr = (unsigned char*)(heap[x][y].alloc_base + offset);
-    *ptr = requested_index;
+    // update the alloc[] array if block found
+    if ( base != 0 )
+    {
+        unsigned offset = (base - heap[x][y].heap_base) / MIN_BLOCK_SIZE;
+        unsigned char* ptr = (unsigned char*)(heap[x][y].alloc_base + offset);
+        *ptr = requested_index;
+    }
 
     // release the lock
@@ -286,9 +293,24 @@
 void free( void* ptr )
 {
-    // To be done
-    // - first : to compute the cluster coordinate
-    // - second : retrieve the block length from the
-    // - third : try to concatenate with another free block of same size
-    // - fourth : update the free[] array
+    unsigned int vaddr = (unsigned int)ptr;
+
+    // get the cluster coordinate
+    unsigned int x;
+    unsigned int y;
+    giet_get_xy( ptr, &x, &y );
+
+    // compute index in alloc[] array
+    unsigned index = ( (unsigned int)ptr - heap[x][y].heap_base ) / MAX_BLOCK_SIZE;
+ 
+    // get the freed block size_index
+    unsigned char* p i        = (unsigned char*)(heap[x][y].alloc_base + index);
+    unsigned int   size_index = (unsigned int)*p;
+
+    // update the free[] array and NEXT pointer
+    *(unsigned int*)ptr         = heap[x][y].free[size_index];
+    heap[x][y].free[size_index] = (unsigned int)ptr;
+    
+    // TODO try to concatenate with another free block of same size
+    // this require probably to replace this simple push by a recursive function
 }
 
Index: /soft/giet_vm/giet_libs/stdio.c
===================================================================
--- /soft/giet_vm/giet_libs/stdio.c	(revision 389)
+++ /soft/giet_vm/giet_libs/stdio.c	(revision 390)
@@ -5,12 +5,41 @@
 // Copyright (c) UPMC-LIP6
 ///////////////////////////////////////////////////////////////////////////////////
-// The stdio.c and stdio.h files are part of the GIET_VM nano-kernel.
-// This library contains all user-level functions that contain a system call
-// to access protected or shared ressources.
-///////////////////////////////////////////////////////////////////////////////////
 
 #include <stdarg.h>
 #include <stdio.h>
 #include <giet_config.h>
+
+////////////////////////////////////////////////////////////////////////////////////
+/////////////////////  MIPS32     related system calls /////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////
+
+/////////////////
+int giet_procid() 
+{
+    return sys_call( SYSCALL_PROCID,
+                     0, 0, 0, 0 );
+}
+
+////////////////////
+int giet_proctime() 
+{
+    return sys_call( SYSCALL_PROCTIME, 
+                     0, 0, 0, 0 );
+}
+
+///////////////
+int giet_rand() 
+{
+    unsigned int x = sys_call(SYSCALL_PROCTIME,
+                              0, 0, 0, 0);
+    if ((x & 0xF) > 7) 
+    {
+        return (x*x & 0xFFFF);
+    }
+    else 
+    {
+        return (x*x*x & 0xFFFF);
+    }
+}
 
 ////////////////////////////////////////////////////////////////////////////////////
@@ -498,5 +527,5 @@
                    (unsigned int)buffer,
                    count, 
-                   offset ) != count ) giet_exit("in giet_fat_read()");
+                   offset ) != count ) giet_exit("ERROR in giet_fat_read()");
 }
 
@@ -511,5 +540,5 @@
                    (unsigned int)buffer,
                    count, 
-                   offset ) != count ) giet_exit("in giet_fat_write()");
+                   offset ) != count ) giet_exit("ERROR in giet_fat_write()");
 }
 
@@ -541,5 +570,5 @@
                    offset, 
                    whence, 
-                   0 ) ) giet_exit("in giet_fat_lseek()");
+                   0 ) ) giet_exit("ERROR in giet_fat_lseek()");
 }
 
@@ -549,5 +578,5 @@
     if ( sys_call( SYSCALL_FAT_FSTAT,
                    fd,
-                   0, 0, 0 ) )  giet_exit("in giet_fat_lseek()");
+                   0, 0, 0 ) )  giet_exit("ERROR in giet_fat_lseek()");
 }
 
@@ -557,25 +586,11 @@
     if ( sys_call( SYSCALL_FAT_CLOSE,
                    fd,
-                   0, 0, 0 ) )  giet_exit("in giet_fat_close()");
-}
-
-
-//////////////////////////////////////////////////////////////////////////////////
-///////////////////// Miscellaneous system calls /////////////////////////////////
-//////////////////////////////////////////////////////////////////////////////////
-
-/////////////////
-int giet_procid() 
-{
-    return sys_call( SYSCALL_PROCID,
-                     0, 0, 0, 0 );
-}
-
-////////////////////
-int giet_proctime() 
-{
-    return sys_call( SYSCALL_PROCTIME, 
-                     0, 0, 0, 0 );
-}
+                   0, 0, 0 ) )  giet_exit("ERROR in giet_fat_close()");
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////
+///////////////////// Task context  system calls /////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 
 ///////////////////////
@@ -600,15 +615,8 @@
 }
 
-///////////////
-int giet_rand() 
-{
-    unsigned int x = sys_call(SYSCALL_PROCTIME, 0, 0, 0, 0);
-    if ((x & 0xF) > 7) {
-        return (x*x & 0xFFFF);
-    }
-    else {
-        return (x*x*x & 0xFFFF);
-    }
-}
+
+//////////////////////////////////////////////////////////////////////////////////
+///////////////////// Miscellaneous system calls /////////////////////////////////
+//////////////////////////////////////////////////////////////////////////////////
 
 //////////////////////////////
@@ -625,4 +633,11 @@
 {
     if ( condition == 0 ) giet_exit( string );
+}
+
+//////////////////////////
+void giet_context_switch() 
+{
+    sys_call( SYSCALL_CTX_SWITCH,
+              0, 0, 0, 0 );
 }
 
@@ -636,5 +651,5 @@
                    (unsigned int) vobj_name,
                    (unsigned int) vobj_vaddr,
-                   0 ) )  giet_exit("in giet_vobj_get_vbase()");
+                   0 ) )  giet_exit("ERROR in giet_vobj_get_vbase()");
 }
 
@@ -646,12 +661,5 @@
                    cluster_id, 
                    (unsigned int) buffer, 
-                   0, 0) )  giet_exit("in giet_proc_number()");
-}
-
-//////////////////////////
-void giet_context_switch() 
-{
-    sys_call( SYSCALL_CTX_SWITCH,
-              0, 0, 0, 0 );
+                   0, 0) )  giet_exit("ERROR in giet_proc_number()");
 }
 
@@ -666,5 +674,17 @@
                    (unsigned int)length, 
                    x,
-                   y ) )  giet_exit("in giet_heap_info()");
+                   y ) )  giet_exit("ERROR in giet_heap_info()");
+}
+
+/////////////////////////////////////////
+void giet_get_xy( void*         ptr,
+                  unsigned int* px,
+                  unsigned int* py )
+{
+    if ( sys_call( SYSCALL_GET_XY,
+                   (unsigned int)ptr,
+                   (unsigned int)px,
+                   (unsigned int)py,
+                   0 ) )  giet_exit("ERROR in giet_get_xy()");
 }
 
Index: /soft/giet_vm/giet_libs/stdio.h
===================================================================
--- /soft/giet_vm/giet_libs/stdio.h	(revision 389)
+++ /soft/giet_vm/giet_libs/stdio.h	(revision 390)
@@ -4,4 +4,8 @@
 // Author   : alain greiner & Joel Porquet
 // Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+// The stdio.c and stdio.h files are part of the GIET_VM nano-kernel.
+// This library contains all user-level functions that contain a system call
+// to access protected or shared ressources.
 ///////////////////////////////////////////////////////////////////////////////////
 
@@ -40,5 +44,5 @@
 #define SYSCALL_CTX_SWITCH        0x19
 #define SYSCALL_VOBJ_GET_VBASE    0x1A
-#define SYSCALL_FREE_1B           0x1B
+#define SYSCALL_GET_XY            0x1B
 #define SYSCALL_NIC_CMA_START     0x1C
 #define SYSCALL_NIC_CMA_STOP      0x1D
@@ -446,4 +450,14 @@
                             unsigned int  y );
 
+//////////////////////////////////////////////////////////////////////////
+// This function takes as input a virtual address (ptr argument), 
+// and returns through the (px,py) arguments the coordinates of 
+// the cluster containing the physical address associated to ptr. 
+// In case of error (unmapped virtual address), it makes a giet_exit().
+//////////////////////////////////////////////////////////////////////////
+extern void giet_get_xy( void*          ptr, 
+                         unsigned int*  px,
+                         unsigned int*  py );
+
 #endif
 
