Index: /soft/giet_vm/Makefile
===================================================================
--- /soft/giet_vm/Makefile	(revision 258)
+++ /soft/giet_vm/Makefile	(revision 259)
@@ -290,4 +290,9 @@
 	$(CC) $(CFLAGS) $(USER_INCLUDE) -c -o $@ $<
 
+build/libs/stdlib.o: giet_libs/stdlib.c \
+                     giet_libs/stdlib.h \
+                     giet_config.h
+	$(CC) $(CFLAGS) $(USER_INCLUDE) -c -o $@ $<
+
 build/libs/string.o: giet_libs/string.c \
                      giet_libs/string.h \
Index: /soft/giet_vm/create_dmg
===================================================================
--- /soft/giet_vm/create_dmg	(revision 258)
+++ /soft/giet_vm/create_dmg	(revision 259)
@@ -8,8 +8,18 @@
 reserved_sectors=32
 
+# FAT32 SPEC: The first two clusters are not present in the data region but
+# they are used in the computation of the FAT sectors
+data_region_clusters=$clusters-2
 
-let "data_sectors = (clusters - 2) * sectors_per_cluster"
-let "fat_sectors = (clusters * 4) / 512"
-let "sectors=data_sectors + fat_sectors + reserved_sectors" 
+let "data_sectors = data_region_clusters * sectors_per_cluster"
+let "fat_sectors  = (clusters * 4) / 512"
+
+# The disk image contains:
+#   - MBR sector : this sector is removed by this script as it will be copied
+#                  after)
+#   - Reserved region sectors (usually 32)
+#   - FAT region sectors
+#   - DATA region sectors
+let "sectors      = data_sectors + fat_sectors + reserved_sectors + 1" 
 
 platform=`uname`
@@ -43,9 +53,9 @@
 			# RAW DISK IMAGE READ-ONLY
 			# The not used space is not considered (smaller disk image)
-			# format="UDRO"
+			format="UDRO"
 
 			# RAW DISK IMAGE READ-WRITE
 			# None compression is made
-			format="UDRW" 
+			# format="UDRW" 
 
 			echo "Creating partition file $3 from $2 directory"
@@ -59,5 +69,5 @@
 				-format $format \
 				$3; 
-# 				-verbose \
+#				-verbose \
 
 			echo "Removing first sector of diskimage"
@@ -106,17 +116,44 @@
 
 elif [[ $platform == "Linux" ]]; then
-	echo "Creating partion file: partition.dmg"
-	mkfs.vfat -C -F32 -S $sector_size -s $sectors_per_cluster \
-		partition.dmg $sectors 
+	case $1 in
+		create )
+			if [[ -z $2 ]]; then
+				echo "Create action need second argument: <srcdir_path>"
+				exit 1;
+			fi;
 
-	echo "Copying files into the partition"
-	mcopy -s -i partition.dmg build :://
-	mcopy -i    partition.dmg map.bin :://
+			if [[ -z $3 ]]; then
+				echo "Create action need third argument: <disk_image>"
+				exit 1;
+			fi;
 
-	echo "Copying MBR on the first sector"
-	dd if=mbr.dmg of=disk.dmg count=1 bs=$sector_size
+			echo "Creating partition file: $3"
 
-	echo "Copying partition file on the sector 200 of the disk"
-	dd if=partition.dmg of=disk.dmg seek=200 bs=$sector_size
+			let "sectors = (sectors - 1) / 2" 
+		    mkfs.vfat \
+				-C \
+				-F32 \
+				-f 1 \
+				-R $reserved_sectors \
+				-S $sector_size \
+				-s $sectors_per_cluster \
+				-v \
+				$3.dmg $sectors
+
+			if [[ -e $2 ]]; then
+				echo "Copying files from $2 into partition"
+				mcopy -s -i $3.dmg $2/* :://
+			fi;;
+
+		* )
+			echo "Pass the command as the first parameter: "
+			echo "  - create: create disk image"
+			echo "            First parameter after create action is the path"
+		    echo "            of the directory to copy in the created "
+			echo "            partition"
+			echo ""
+			echo "EXAMPLES:"
+			echo " ./create_diskimage.sh create /path/to/source_dir disk_image"
+	esac;
 
 else
Index: /soft/giet_vm/giet_fat32/fat32.c
===================================================================
--- /soft/giet_vm/giet_fat32/fat32.c	(revision 258)
+++ /soft/giet_vm/giet_fat32/fat32.c	(revision 259)
@@ -1163,8 +1163,147 @@
                 unsigned int offset )    // nuber of sectors to skip in file
 {
-    _tty_get_lock( 0 );
-    _puts("\n[FAT ERROR] _fat_write() function not implemented\n");
-    _tty_release_lock( 0 );
-    return -1;
+
+    unsigned int spc = fat.sectors_per_cluster;
+
+    unsigned int file_size;         // number of bytes in file
+    unsigned int file_sectors;      // number of sectors in file
+    unsigned int cluster;           // cluster index 
+    unsigned int clusters_to_skip;  // number of clusters to skip because offset
+    unsigned int sectors_to_skip;   // number of sectors to skip in first iteration
+    unsigned int allocate;          // need allocate or not
+
+    // compute file size as a number of sectors 
+    file_size    = fat.fd[fd_id].file_size;
+    if ( file_size & 0x1FF ) file_sectors = (file_size >> 9) + 1;
+    else                     file_sectors = (file_size >> 9); 
+    
+    allocate = ( ((count + offset) / spc) > (file_sectors / spc) );
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] Enter _fat_write() for file ");
+_puts( fat.fd[fd_id].name );
+_puts("\n - buffer base     = ");
+_putx( (unsigned int)buffer );
+_puts("\n - skipped sectors = ");
+_putd( offset );
+_puts("\n - write sectors    = "); 
+_putd( count );
+_puts("\n - file size (sectors)  = "); 
+_putd( file_sectors );
+_puts("\n - need allocate = "); 
+allocate ? _puts( "True" ) : _puts( "False");
+_tty_release_lock( 0 );
+#endif
+
+    if ( allocate  )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_write() : \n");
+        _puts("we need to allocate more cluster... But this function is not implemented\n");
+        _tty_release_lock( 0 );
+        return -1;
+    }
+    // arguments checking
+    if ( fd_id >= GIET_OPEN_FILES_MAX )
+    { 
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_write() : illegal file descriptor index\n");
+        _tty_release_lock( 0 );
+        return -1;
+    }
+    if ( fat.fd[fd_id].used != 1 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_write() : file not open\n");
+        _tty_release_lock( 0 );
+        return -1;
+    }
+    if ( ((unsigned int)buffer & 0x1FF) != 0 )
+    {
+        _tty_get_lock( 0 );
+        _puts("\n[FAT ERROR] in _fat_write() : memory buffer not sector aligned\n");
+        _tty_release_lock( 0 );
+        return -1;
+    }
+
+    // compute clusters and sectors to be skipped
+    clusters_to_skip = offset / spc;
+    sectors_to_skip  = offset % spc;
+    
+    // get first cluster index 
+    cluster = fat.fd[fd_id].first_cluster;
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n - first cluster   = ");
+_putd( cluster );   
+_puts("\n - skiped clusters = ");
+_putd( clusters_to_skip );   
+_puts("\n");
+_tty_release_lock( 0 );
+#endif
+
+    // compute index of first cluster to be loaded
+    // as we may need to scan the FAT, we use the kernel mode
+    while ( clusters_to_skip )
+    {
+        cluster = get_next_cluster_id( IOC_KERNEL_MODE, cluster );
+        clusters_to_skip--;
+    }
+
+    // variables used in the loop on clusters
+    int             todo_sectors;   // number of sectors still to be loaded
+    unsigned int    lba;            // first sector index on device
+    unsigned int    iter_sectors;   // number of sectors to load in iteration
+    char*           src;            // pointer on target buffer
+
+    // initialize these variables for the first iteration 
+    todo_sectors  = count;
+    src           = (char*)buffer;
+    lba           = cluster_to_lba(cluster) + sectors_to_skip;
+    if( count < (spc - sectors_to_skip) ) iter_sectors = count;
+    else                                  iter_sectors = spc - sectors_to_skip; 
+
+    // loop on the clusters
+    while ( todo_sectors > 0 )
+    {
+
+#if GIET_DEBUG_FAT
+_tty_get_lock( 0 );
+_puts("\n[FAT DEBUG] _fat_write() IOC request : buf = ");
+_putx( (unsigned int)src );
+_puts(" / lba = ");
+_putd( lba );
+_puts(" / sectors = "); 
+_putd( iter_sectors );
+_puts("\n");  
+_tty_release_lock( 0 );
+#endif
+
+        if( _ioc_write( mode,              // mode for IOC driver
+                        lba,               // first sector index 
+                        src,               // buffer address
+                        iter_sectors ) )   // number of sectors
+        {
+            _tty_get_lock( 0 );
+            _puts("\n[FAT ERROR] in _fat_write() cannot write block ");
+            _putd( lba );
+            _puts("\n"); 
+            _tty_release_lock( 0 );
+            return -1;
+        }
+         
+        // update variables for next iteration
+        cluster      = get_next_cluster_id( mode, cluster );
+        todo_sectors = todo_sectors - iter_sectors;
+        src          = src + (iter_sectors << 9);
+        lba          = cluster_to_lba(cluster);
+        if ( todo_sectors > spc ) iter_sectors = spc;
+        else                      iter_sectors = todo_sectors;
+    }
+         
+    // returns number of sectors actually transfered
+    return count;
 }
 
Index: /soft/giet_vm/giet_libs/stdio.h
===================================================================
--- /soft/giet_vm/giet_libs/stdio.h	(revision 258)
+++ /soft/giet_vm/giet_libs/stdio.h	(revision 259)
@@ -48,7 +48,7 @@
 #define SYSCALL_FAT_OPEN          0x20
 #define SYSCALL_FAT_READ          0x21
-#define SYSCALL_FAT_WRITE         0x21
-#define SYSCALL_FAT_LSEEK         0x21
-#define SYSCALL_FAT_CLOSE         0x21
+#define SYSCALL_FAT_WRITE         0x22
+#define SYSCALL_FAT_LSEEK         0x23
+#define SYSCALL_FAT_CLOSE         0x24
 
 //////////////////////////////////////////////////////////////////////////////////
Index: /soft/giet_vm/giet_libs/stdlib.c
===================================================================
--- /soft/giet_vm/giet_libs/stdlib.c	(revision 259)
+++ /soft/giet_vm/giet_libs/stdlib.c	(revision 259)
@@ -0,0 +1,39 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : stdlib.c 
+// Date     : 05/12/2013
+// Author   : ClÃ©ment DEVIGNE
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////////////////////
+// int atoi ( char * str )
+///////////////////////////////////////////////////////////////////////////////////
+        
+int atoi(char *str)
+{
+    int res  = 0; // Initialize result
+    int sign = 1; // Initialize sign as positive
+    int i    = 0; // Initialize index of first digit
+
+    if (str[0] == '-') //If number is negative, then update sign
+    {
+        sign = -1;  
+        i++;           // Also update index of first digit
+    }
+
+    for (; str[i] != '\0'; ++i) // Iterate through all digits and update the result
+    {
+        res = res*10 + str[i] - '0';
+    }
+
+    // Return result with sign
+    return sign*res;
+}
+        
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Index: /soft/giet_vm/giet_libs/stdlib.h
===================================================================
--- /soft/giet_vm/giet_libs/stdlib.h	(revision 259)
+++ /soft/giet_vm/giet_libs/stdlib.h	(revision 259)
@@ -0,0 +1,20 @@
+//////////////////////////////////////////////////////////////////////////////////
+// File     : stdlib.h 
+// Date     : 05/12/2013
+// Author   : ClÃ©ment DEVIGNE
+// Copyright (c) UPMC-LIP6
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef _STDLIB_H
+#define _STDLIB_H
+
+int atoi (char * str);
+#endif
+
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// c-file-offsets:((innamespace . 0)(inline-open . 0))
+// indent-tabs-mode: nil
+// End:
+// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
