Index: soft/giet_vm/giet_kernel/kernel_init.c
===================================================================
--- soft/giet_vm/giet_kernel/kernel_init.c	(revision 459)
+++ soft/giet_vm/giet_kernel/kernel_init.c	(revision 467)
@@ -12,4 +12,5 @@
 #include <utils.h>
 #include <tty0.h>
+#include <kernel_malloc.h>
 #include <fat32.h>
 #include <xcu_driver.h>
@@ -60,10 +61,25 @@
 #endif
 
+#if !defined(NB_TTY_CHANNELS)
+# error: You must define NB_TTY_CHANNELS in the hard_config.h file
+#endif
+
+#if (NB_TTY_CHANNELS < 1)
+# error: NB_TTY_CHANNELS cannot be smaller than 1
+#endif
+
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// Ditributed kernel heap descriptors array (for dynamic memory allocation)
+///////////////////////////////////////////////////////////////////////////////////
+
+kernel_heap_t  kernel_heap[X_SIZE][Y_SIZE];
+
 ///////////////////////////////////////////////////////////////////////////////////
 // FAT internal representation for kernel code
 ///////////////////////////////////////////////////////////////////////////////////
 
-__attribute__((section (".kdata"))) 
-fat32_fs_t fat __attribute__((aligned(512)));
+fat32_fs_t     fat      __attribute__((aligned(512)));
 
 ///////////////////////////////////////////////////////////////////////////////////
@@ -71,16 +87,12 @@
 ///////////////////////////////////////////////////////////////////////////////////
 
-__attribute__((section (".kdata"))) 
 volatile unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX];    // virtual addresses
-
-__attribute__((section (".kdata")))        
 volatile unsigned int _ptabs_ptprs[GIET_NB_VSPACE_MAX];    // physical addresses >> 13
 
 ///////////////////////////////////////////////////////////////////////////////////
-// array of pointers on the schedulers (physical addresses)
-///////////////////////////////////////////////////////////////////////////////////
-
-__attribute__((section (".kdata"))) 
-volatile static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 
+// Array of pointers on the schedulers (physical addresses)
+///////////////////////////////////////////////////////////////////////////////////
+
+volatile static_scheduler_t*    _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX]; 
 
 ////////////////////////////////////////////////////////////////////////////////////
@@ -88,13 +100,35 @@
 ////////////////////////////////////////////////////////////////////////////////////
 
-__attribute__((section (".kdata"))) 
 volatile unsigned int kernel_init_barrier = 0;
 
+////////////////////////////////////////////////////////////////////////////////////
+// Global variables for TTY/kernel communications
+////////////////////////////////////////////////////////////////////////////////////
+
+sbt_lock_t     _tty_tx_lock[NB_TTY_CHANNELS]  __attribute__((aligned(64)));
+
+unsigned int   _tty_rx_buf[NB_TTY_CHANNELS];
+unsigned int   _tty_rx_full[NB_TTY_CHANNELS]; 
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// This kernel_init() function completes the kernel initialisation in 7 steps:
+// All processors execute this code, but this is done sequencially.
+// - step 0 : Initialise fat, heap descriptors, and tty locks
+// - step 1 : Initialise scheduler pointers array
+// - step 2 : Initialise PTAB pointers arrays
+// - step 3 : Initialise private XCU masks
+// - step 4 :
+// - step 5 :
+// - step 6 :
 ///////////////////////////////////////////////////////////////////////////////////
 __attribute__((section (".kinit"))) void kernel_init() 
 {
     // gpid : hardware processor index (fixed format: X_WIDTH|Y_WIDTH|P_WIDTH)
-    // p : local processor id in a cluster ( p < NB_PROCS_MAX)
-    // cpid : "continuous" processor index = (((x * Y_SIZE + y) * NB_PROCS_MAX) + p 
+    // p    : local processor id in a cluster ( p < NB_PROCS_MAX)
+    // cpid : continuous processor index = (((x * Y_SIZE + y) * NB_PROCS_MAX) + p 
 
     unsigned int gpid       = _get_procid();
@@ -105,10 +139,33 @@
     unsigned int cpid       = ((( x * Y_SIZE) + y) * NB_PROCS_MAX) + p;
 
-
     // This initialisation is done sequencially by each processor
     while( cpid != kernel_init_barrier ) asm volatile ( "nop" );
 
-    // Step 0 : Processor[0,0,0] initialises the kernel FAT
-    if ( gpid == 0 ) _fat_init( IOC_BOOT_MODE ); 
+    // Step 0 : P[0,0,0] initialises the kernel FAT 
+    //          and the distributed kernel_heap descriptors array. 
+    if ( gpid == 0 )
+    {
+        _heap_init();
+        
+#if GIET_DEBUG_INIT
+_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel HEAP init\n", x, y, p );
+#endif
+        unsigned int channel;
+        for ( channel = 0 ; channel < NB_TTY_CHANNELS ; channel++ )
+        {
+            _sbt_lock_init( &_tty_tx_lock[channel] );
+        }
+
+#if GIET_DEBUG_INIT
+_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes TTY locks init\n", x, y, p );
+#endif
+
+        _fat_init( IOC_BOOT_MODE ); 
+
+#if GIET_DEBUG_INIT
+_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] completes kernel FAT init\n", x, y, p );
+#endif
+
+    }
 
     // Step 1 : each processor get its scheduler virtual address from CP0_SCHED register
@@ -121,8 +178,8 @@
 
 #if GIET_DEBUG_INIT
-_printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] starts kernel init\n"
-        " - scheduler vbase = %x\n"
-        " - tasks           = %d\n",
-        x, y, p, (unsigned int)psched, tasks );
+_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises SCHED array\n"
+               " - scheduler vbase = %x\n"
+               " - tasks           = %d\n",
+               x, y, p, (unsigned int)psched, tasks );
 #endif
 
@@ -148,5 +205,5 @@
 
 #if GIET_DEBUG_INIT
-_printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] contributes to PTABS arrays\n"
+_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initialises PTABS arrays\n"
         " - ptabs_vaddr[%d] = %x / ptpr_paddr[%d] = %l\n",
         x, y, p,  
@@ -167,10 +224,10 @@
 
 #if GIET_DEBUG_INIT
-_printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] updates context for task %d\n"
-        " - ctx_epc   = %x\n"
-        " - ctx_ra    = %x\n",
-        x, y, p, ltid,
-        _get_task_slot( x, y, p, ltid, CTX_EPC_ID ),
-        _get_task_slot( x, y, p, ltid, CTX_RA_ID ) );
+_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] updates context for task %d\n"
+               " - ctx_epc   = %x\n"
+               " - ctx_ra    = %x\n",
+               x, y, p, ltid,
+               _get_task_slot( x, y, p, ltid, CTX_EPC_ID ),
+               _get_task_slot( x, y, p, ltid, CTX_RA_ID ) );
 #endif
 
@@ -202,9 +259,9 @@
 
 #if GIET_DEBUG_INIT
-_printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] sets XCU masks\n"
-        " - XCU HWI_MASK = %x\n"
-        " - XCU WTI_MASK = %x\n"
-        " - XCU PTI_MASK = %x\n",
-        x, y, p, hwi_mask, wti_mask, pti_mask );
+_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] sets XCU masks\n"
+               " - XCU HWI_MASK = %x\n"
+               " - XCU WTI_MASK = %x\n"
+               " - XCU PTI_MASK = %x\n",
+               x, y, p, hwi_mask, wti_mask, pti_mask );
 #endif
 
@@ -221,6 +278,6 @@
         if (isr_switch_index == 0xFFFFFFFF) 
         {
-            _printf("\n[GIET ERROR] ISR_TICK not found for processor[%d,%d,%d]\n",
-                    x, y, p );
+            _nolock_printf("\n[GIET ERROR] ISR_TICK not found for processor[%d,%d,%d]\n",
+                           x, y, p );
             _exit();
         }
@@ -232,6 +289,6 @@
 
 #if GIET_DEBUG_INIT
-_printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] starts TICK timer\n",
-        x, y, p );
+_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] starts TICK timer\n",
+               x, y, p );
 #endif
 
@@ -249,8 +306,8 @@
 
 #if GIET_DEBUG_INIT
-_printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] initializes IDLE task\n"
-        " - stack_base = %x\n"
-        " - stack_size = 0x1000\n",
-        x, y, p, pstack - 0x1000 );
+_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes IDLE task\n"
+               " - stack_base = %x\n"
+               " - stack_size = 0x1000\n",
+               x, y, p, pstack - 0x1000 );
 #endif
 
@@ -265,6 +322,6 @@
         ltid = IDLE_TASK_INDEX;
 
-        _printf("\n[GIET WARNING] No task allocated to processor[%d,%d,%d]\n",
-                x, y, p );
+        _nolock_printf("\n[GIET WARNING] No task allocated to processor[%d,%d,%d]\n",
+                       x, y, p );
     }
     else
@@ -279,6 +336,6 @@
 
 #if GIET_DEBUG_INIT
-_printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] reach barrier at cycle %d\n",
-        x, y, p, _get_proctime() );
+_nolock_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] reach barrier at cycle %d\n",
+               x, y, p, _get_proctime() );
 #endif
 
@@ -290,5 +347,5 @@
 
 #if GIET_DEBUG_INIT
-_printf("\n[GIET DEBUG INIT] Processor[%d,%d,%d] initializes registers at cycle %d\n"
+_printf("\n[DEBUG KERNEL_INIT] P[%d,%d,%d] initializes registers at cycle %d\n"
         " - sp   = %x\n"
         " - sr   = %x\n"
