Difference between revisions of "FatFS"

From ERIKA WIKI
Jump to: navigation, search
(Sharing a FAT file system with Linux)
(Introduction)
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
= Introduction =
 
= Introduction =
  
FatFs is a tiny library which provides FAT/exFAT support for small embedded systems.
+
FatFs is a tiny library which provides FAT/exFAT support for small embedded systems.<br>
File system functionalities are separated from the disk I/O layer and are easy to configure by enabling/disabling [http://elm-chan.org/fsw/ff/doc/config.html options].<br>
+
The stack support will be provided starting from '''GH63''' release of Erika with a '''memory driver''' which basically exports a portion of memory as a '''block device'''. The memory which file system is built upon can be private in Erika or shared between Erika and other guests (e.g. Linux).<br>
The stack support will be provided in the next release of Erika with a '''memory driver''' which basically exports a portion of memory as a '''block device'''.<br>
 
 
The following sections describe how to use use a subset of basic functionalities of FatFs.
 
The following sections describe how to use use a subset of basic functionalities of FatFs.
 +
 +
= FatFs features =
 +
As described in the FatFs's main web page, this library offers the following features:<br>
 +
<ul>
 +
<li> DOS/Windows compatible FAT/exFAT filesystem
 +
<li> Long file name in ANSI/OEM or Unicode
 +
<li> exFAT filesystem
 +
<li> Thread safe for RTOS
 +
<li> Multiple volumes (physical drives and partitions)
 +
<li> Variable sector size
 +
</ul>
 +
 +
File system functionalities are separated from the disk I/O layer. This [http://elm-chan.org/fsw/ff/doc/config.html page] lists all the available FatFs functionalities which can be enabled/disabled.<br>
  
 
= Erika/FatFS demo on Jetson TX2 with Jailhouse Hypervisor (aarch64) =
 
= Erika/FatFS demo on Jetson TX2 with Jailhouse Hypervisor (aarch64) =
Line 11: Line 23:
 
<ol>
 
<ol>
 
<li> Download the FatFs library as archive from the Download section on [http://elm-chan.org/fsw/ff/00index_e.html http://elm-chan.org/fsw/ff/00index_e.html] or simply clone the Git reposity from [https://github.com/RIOT-OS/FatFS.git https://github.com/RIOT-OS/FatFS.git]
 
<li> Download the FatFs library as archive from the Download section on [http://elm-chan.org/fsw/ff/00index_e.html http://elm-chan.org/fsw/ff/00index_e.html] or simply clone the Git reposity from [https://github.com/RIOT-OS/FatFS.git https://github.com/RIOT-OS/FatFS.git]
<li> In the FatFs downloaded sources enable the [http://elm-chan.org/fsw/ff/doc/config.html#use_lfn Long Filename Support] and the [http://elm-chan.org/fsw/ff/doc/mkfs.html Mkfs] function (in <code>/full/paty/FatFS/source/ffconf.h</code> enable the defines <code>#define FF_USE_LFN  1</code> and <code>#define FF_USE_MKFS   1</code>)
+
<li> In the FatFs downloaded sources enable the [http://elm-chan.org/fsw/ff/doc/config.html#use_lfn Long Filename Support] and the [http://elm-chan.org/fsw/ff/doc/mkfs.html Mkfs] function as follows.<br> In <code>/full/path/FatFS/source/ffconf.h</code>:<br>
 +
<ul>
 +
<li> enable <code>#define FF_USE_LFN  1</code>
 +
<li> enable <code>#define FF_USE_MKFS 1</code>.
 +
</ul>
 
<li> Set the build environment as described in [[Nvidia Jetson TX1 and TX2]] (cross-toolchain, Jetson platform setup, Jailhouse cross-compiling)
 
<li> Set the build environment as described in [[Nvidia Jetson TX1 and TX2]] (cross-toolchain, Jetson platform setup, Jailhouse cross-compiling)
 
<li> Run the RT-Druid tool
 
<li> Run the RT-Druid tool
Line 18: Line 34:
 
<li> Name the new project (e.g., <code>mytest</code>) and select the Cross-GCC as shown in the next Figure:
 
<li> Name the new project (e.g., <code>mytest</code>) and select the Cross-GCC as shown in the next Figure:
 
[[File:Eclipse_new_project2.jpg|thumb|center|Figure 2: Naming the new RT-Druid project.]]
 
[[File:Eclipse_new_project2.jpg|thumb|center|Figure 2: Naming the new RT-Druid project.]]
<li> Check the box for using an existing template and select <code>aarch64</code> &rarr; <code>Jailhouse</code> &rarr; <code>FatFs</code> &rarr;<code>FatFs usage on memory</code>as shown in the next Figure:
+
<li> Import a <code>main.c</code> and a <code>conf.oil</code> from an existing template by checking the box <code>Create a project using one of these templates</code> and selecting <code>aarch64</code> &rarr; <code>Jailhouse</code> &rarr; <code>FatFs</code> &rarr;<code>FatFs usage on memory</code>as shown in the next Figure:
 
[[File:Eclipse_fatfs_template.jpg|thumb|center|Figure 3: Selecting the FatFs template.]]
 
[[File:Eclipse_fatfs_template.jpg|thumb|center|Figure 3: Selecting the FatFs template.]]
 
<li> Right click the project and select <code>Properties</code> as shown in the following Figure:
 
<li> Right click the project and select <code>Properties</code> as shown in the following Figure:
Line 29: Line 45:
 
== Creating a private FAT file system on Erika ==
 
== Creating a private FAT file system on Erika ==
  
When the <code>#define EE_MEM_LOCAL</code> is enabled in <code>main.c</code>, Erika will perform such actions:
+
In order to create a private FAT file system on Erika, the <code>#define EE_MEM_LOCAL</code> must be enabled in <code>main.c</code> provided by the RT-Druid template (described above), Erika will perform such actions:
 
<ol>
 
<ol>
 
<li> Before starting OS, will:
 
<li> Before starting OS, will:
Line 44: Line 60:
 
== Sharing a FAT file system with Linux  ==
 
== Sharing a FAT file system with Linux  ==
  
When the <code>#define EE_MEM_LOCAL</code> is disabled in <code>main.c</code>, Erika expects to find a valid FAT file system
+
In order to share a FAT file system with Linux, the <code>#define EE_MEM_LOCAL</code> must be disabled in <code>main.c</code>.<br>
at the address location <code>#define memory (const void*)(0x274800000)</code>.<br>
+
 
This address represents the start of a shared memory region between Erika and Linux where the latter must provide a valid file system (see next subsections).<br>
+
Erika expects to find a valid FAT file system at a given address location.
 +
This address represents the start of a physical shared memory region between Erika and Linux where the latter must provide a valid file system (see next subsections).<br>
 +
 
 
After proper <code>fmem</code> initialization with the shared memory address, Erika will perform the same actions of directory/file creation described in the previous example.<br>
 
After proper <code>fmem</code> initialization with the shared memory address, Erika will perform the same actions of directory/file creation described in the previous example.<br>
Please note that the memory region must be mapped into the <code>inmate address space</code> through the <code>map_range</code> function.<br>
+
Please note that the memory region is mapped into the <code>inmate address space</code> through the <code>map_range</code> function.<br>
 +
 
 +
=== Setup of the Jailhouse environment  ===
 +
 
 +
Jailhouse should be aware of this shared region. This is achieved by putting in both the <code>root cell</code> and <code>inmate cell</code> the following section:
 +
               
 +
  {   
 +
    .phys_start = 0x274800000,
 +
    .virt_start = 0x274800000,
 +
    .size = 0x80000,
 +
    .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE
 +
            | JAILHOUSE_MEM_ROOTSHARED,
 +
  },
  
Furthermore Jailhouse should be aware of this shared region. This is achieved by putting in both the <code>root cell</code> and <code>inmate cell</code> the section:<br>
+
where <code>0x274800000</code> is the physical start address of the shared region (given by the flag <code>JAILHOUSE_MEM_ROOTSHARED</code>).<br>
<code>                
+
Thus Erika expects the <code>memory</code> macro to be initialized with such value (e.g. <code>#define memory (const void*)(0x274800000)</code>).<br>
                {   
 
                        .phys_start = 0x274800000,
 
                        .virt_start = 0x274800000,
 
                        .size = 0x80000,
 
                        .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE
 
                        | JAILHOUSE_MEM_ROOTSHARED,
 
                  },
 
</code><br>
 
  
'''NOTE:''' configurations sources are <code>jetson-tx2.c</code> and <code>jetson-tx2-demo.c</code> located in the folder <code>configs/arm64</code> of the Evidence Jailhouse repository cloned from [https://github.com/evidence/linux-jailhouse-jetson.git https://github.com/evidence/linux-jailhouse-jetson.git]. Don't forget to increase the <code>struct jailhouse_memory mem_regions</code>number at the beginning of the files. Furthermore the executable size (including the FatFs library) could not fit the default RAM size assigned to the inmate. Increase it to <code>0x100000</code> in the <code>RAM memregion</code> in <code>configs/arm64/jetson-tx2-demo.c</code> and in the function <code>arch_mmu_enable</code> in <code>inmates/lib/arm-common/mem.c</code>.<br>
+
Furthermore the executable size (including the FatFs library) could not fit the default RAM size assigned to the inmate by default.
After configurations' update, they must be rebuilt (follow instruction in the <code>README.md</code> of the Hypervisor repository).<br>
+
This implies the following changes to be applied to your Jailhouse working copy  cloned from [https://github.com/evidence/linux-jailhouse-jetson.git https://github.com/evidence/linux-jailhouse-jetson.git]:
 +
 
 +
<ol>
 +
<li> in <code>configs/arm64/jetson-tx2.c</code>:
 +
<ul>
 +
<li> increase memregions numbers:</li>
 +
 
 +
  - struct jailhouse_memory mem_regions[66];
 +
  + struct jailhouse_memory mem_regions[67];
 +
 
 +
<li> add the shared memory at the end of listed memregions as described above
 +
</ul>
 +
 
 +
<li> in <code>configs/arm64/jetson-tx-demo.c</code>:
 +
<ul>
 +
<li> increase memregions numbers:</li>
 +
 
 +
  - struct jailhouse_memory mem_regions[5];
 +
  + struct jailhouse_memory mem_regions[6];
 +
 
 +
<li> increase inmate's RAM size:</li>
 +
 
 +
    /* RAM */ {
 +
    .phys_start = 0x270000000,
 +
    .virt_start = 0,
 +
  - .size = 0x10000,
 +
  + .size = 0x100000,
 +
    .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
 +
            JAILHOUSE_MEM_EXECUTE | JAILHOUSE_MEM_LOADABLE,
 +
 
 +
<li> add the shared memory at the end of listed memregions as described above
 +
</ul>
 +
 
 +
<li> in <code>inmates/lib/arm-common/mem.c</code>:
 +
<ul>  
 +
<li> increase inmate's RAM mapping:</li>
 +
 
 +
  void arch_mmu_enable(void)
 +
  {
 +
          unsigned long mair, sctlr;
 +
 
 +
  -      map_range((void*)CONFIG_INMATE_BASE, 0x10000, MAP_CACHED);
 +
  +      map_range((void*)CONFIG_INMATE_BASE, 0x100000, MAP_CACHED);
 +
          map_range((void*)COMM_REGION_BASE, PAGE_SIZE, MAP_CACHED);
 +
 
 +
</ul>
 +
</ol>  
 +
 
 +
=== FatFs on Linux side  ===
 +
 
 +
Linux can provide a file system to Erika with the help of the FatFs library which can be built for Linux as well. To build the library for Linux just use the following commands:
  
Linux can provide a file system to Erika with the help of the FatFs library which can be built for Linux as well. To build the library for Linux just use the following commands:<br>
 
<code>
 
 
       :~ mkdir fatfs-linux-build
 
       :~ mkdir fatfs-linux-build
 
       :~ aarch64-linux-gnu-gcc -DFATFS_LINUX -I ''/full/erika3/path/''contrib/fatfs/diskio/memory/ -I ''/full/FatFs/path/''source/  
 
       :~ aarch64-linux-gnu-gcc -DFATFS_LINUX -I ''/full/erika3/path/''contrib/fatfs/diskio/memory/ -I ''/full/FatFs/path/''source/  
Line 72: Line 142:
 
                                                 ''/full/FatFs/path/''source/ffunicode.c  
 
                                                 ''/full/FatFs/path/''source/ffunicode.c  
 
         :~ aarch64-linux-gnu-ar rcs libfatfs.a *.o
 
         :~ aarch64-linux-gnu-ar rcs libfatfs.a *.o
</code>
 
  
Now that library is built, you can use <code>main.c</code> which looks similar to the one provided with the FatFs Erika demo. FatFs functions are the same indeed (except for the handling of system time which is correctly taken from Linux time). The main difference with the Erika application is in the shared memory's mapping which is performed with <code>mmap</code> in order to be accessed by the application. A code snippet which performs such mapping could be the following:<br>
+
Now that library is built, you can edit a <code>main.c</code> which looks similar to the one provided with the FatFs Erika demo. FatFs functions are the same indeed (except for the handling of system time which is correctly taken from Linux time). The main difference with the Erika application is in the shared memory's mapping which is performed with <code>mmap</code> in order to be accessed by the application. A code snippet which performs such mapping could be the following:
  
<code>
 
 
         long int physical_address = 0x274800000;
 
         long int physical_address = 0x274800000;
 
         size_t memory_size = MINIMUM_FAT_SIZE;
 
         size_t memory_size = MINIMUM_FAT_SIZE;
Line 85: Line 153:
 
                         physical_address);
 
                         physical_address);
 
         }
 
         }
</code>
 
  
After calling this function with proper parameters, init the <code>fmem</code> drive with <code>f_mem_init(process_memory_address, memory_size)</code> and then create/modify the FAT file system (use <code>f_mkfs</code>, <code>f_mount</code> and friends...).
+
After calling this function with proper parameters, the application must init the <code>fmem</code> drive with <code>f_mem_init(process_memory_address, memory_size)</code> and then create/modify the FAT file system (use <code>f_mkfs</code>, <code>f_mount</code> and friends...).
 +
 
 +
Link your main with the library:
  
Link your main with the library:<br>
 
<code>
 
 
       :~ aarch64-linux-gnu-gcc  -I ''/full/erika3/path/''contrib/fatfs/diskio/memory/ -I ''/full/FatFs/path/''source/  
 
       :~ aarch64-linux-gnu-gcc  -I ''/full/erika3/path/''contrib/fatfs/diskio/memory/ -I ''/full/FatFs/path/''source/  
 
                                                 -c main.c -L''/full/path/fatfs-linux-build'' -lfatfs
 
                                                 -c main.c -L''/full/path/fatfs-linux-build'' -lfatfs
</code>
+
 
  
 
First execute the Linux application and then the Erika inmate. The latter will show all the directories/files you decided to create.
 
First execute the Linux application and then the Erika inmate. The latter will show all the directories/files you decided to create.

Latest revision as of 17:05, 8 April 2019

Introduction

FatFs is a tiny library which provides FAT/exFAT support for small embedded systems.
The stack support will be provided starting from GH63 release of Erika with a memory driver which basically exports a portion of memory as a block device. The memory which file system is built upon can be private in Erika or shared between Erika and other guests (e.g. Linux).
The following sections describe how to use use a subset of basic functionalities of FatFs.

FatFs features

As described in the FatFs's main web page, this library offers the following features:

  • DOS/Windows compatible FAT/exFAT filesystem
  • Long file name in ANSI/OEM or Unicode
  • exFAT filesystem
  • Thread safe for RTOS
  • Multiple volumes (physical drives and partitions)
  • Variable sector size

File system functionalities are separated from the disk I/O layer. This page lists all the available FatFs functionalities which can be enabled/disabled.

Erika/FatFS demo on Jetson TX2 with Jailhouse Hypervisor (aarch64)

This demo shows how to handle directories/files on a FAT file system on Erika Enterpries v3 running as a Jailhouse inmate on Jetson TX2 board:

  1. Download the FatFs library as archive from the Download section on http://elm-chan.org/fsw/ff/00index_e.html or simply clone the Git reposity from https://github.com/RIOT-OS/FatFS.git
  2. In the FatFs downloaded sources enable the Long Filename Support and the Mkfs function as follows.
    In /full/path/FatFS/source/ffconf.h:
    • enable #define FF_USE_LFN 1
    • enable #define FF_USE_MKFS 1.
  3. Set the build environment as described in Nvidia Jetson TX1 and TX2 (cross-toolchain, Jetson platform setup, Jailhouse cross-compiling)
  4. Run the RT-Druid tool
  5. Create a new project by clicking on NewRT-Druid v3 Oil and C/C++ Project as shown in the next Figure:
    Figure 1: Create a new RT-Druid project.
  6. Name the new project (e.g., mytest) and select the Cross-GCC as shown in the next Figure:
    Figure 2: Naming the new RT-Druid project.
  7. Import a main.c and a conf.oil from an existing template by checking the box Create a project using one of these templates and selecting aarch64JailhouseFatFsFatFs usage on memoryas shown in the next Figure:
    Figure 3: Selecting the FatFs template.
  8. Right click the project and select Properties as shown in the following Figure:
    Figure 4: Eclipse project properties.
  9. Click OilGenerator properties, enable project specific settings and specify the directory containing the FatFs library for ERIKA3:
    Figure 5: Setting the path of the FatFs library.
  10. Configure the RT-Druid as described in Nvidia Jetson TX1 and TX2#RT-Druid set-up

Creating a private FAT file system on Erika

In order to create a private FAT file system on Erika, the #define EE_MEM_LOCAL must be enabled in main.c provided by the RT-Druid template (described above), Erika will perform such actions:

  1. Before starting OS, will:
    • inizialize the fmem driver
    • create a FAT file system on an array located in .data section of the executable
    • create the directory test
    • create the file erika.txt in the directory test
  2. The Task1 will dump the directories and files content ( output should look like this):
    Figure 6: Application output on private file system.

Sharing a FAT file system with Linux

In order to share a FAT file system with Linux, the #define EE_MEM_LOCAL must be disabled in main.c.

Erika expects to find a valid FAT file system at a given address location. This address represents the start of a physical shared memory region between Erika and Linux where the latter must provide a valid file system (see next subsections).

After proper fmem initialization with the shared memory address, Erika will perform the same actions of directory/file creation described in the previous example.
Please note that the memory region is mapped into the inmate address space through the map_range function.

Setup of the Jailhouse environment

Jailhouse should be aware of this shared region. This is achieved by putting in both the root cell and inmate cell the following section:

 {     
   .phys_start = 0x274800000,
   .virt_start = 0x274800000,
   .size = 0x80000,
   .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE
            | JAILHOUSE_MEM_ROOTSHARED,
 },

where 0x274800000 is the physical start address of the shared region (given by the flag JAILHOUSE_MEM_ROOTSHARED).
Thus Erika expects the memory macro to be initialized with such value (e.g. #define memory (const void*)(0x274800000)).

Furthermore the executable size (including the FatFs library) could not fit the default RAM size assigned to the inmate by default. This implies the following changes to be applied to your Jailhouse working copy cloned from https://github.com/evidence/linux-jailhouse-jetson.git:

  1. in configs/arm64/jetson-tx2.c:
    • increase memregions numbers:
    •  - struct jailhouse_memory mem_regions[66];
       + struct jailhouse_memory mem_regions[67];
      
    • add the shared memory at the end of listed memregions as described above
  2. in configs/arm64/jetson-tx-demo.c:
    • increase memregions numbers:
    •  - struct jailhouse_memory mem_regions[5];
       + struct jailhouse_memory mem_regions[6];
      
    • increase inmate's RAM size:
    •    /* RAM */ {
         .phys_start = 0x270000000,
         .virt_start = 0,
       - .size = 0x10000,
       + .size = 0x100000,
         .flags = JAILHOUSE_MEM_READ | JAILHOUSE_MEM_WRITE |
                  JAILHOUSE_MEM_EXECUTE | JAILHOUSE_MEM_LOADABLE,
      
    • add the shared memory at the end of listed memregions as described above
  3. in inmates/lib/arm-common/mem.c:
    • increase inmate's RAM mapping:
    •  void arch_mmu_enable(void)
        {
               unsigned long mair, sctlr;
        
       -       map_range((void*)CONFIG_INMATE_BASE, 0x10000, MAP_CACHED);
       +       map_range((void*)CONFIG_INMATE_BASE, 0x100000, MAP_CACHED);
               map_range((void*)COMM_REGION_BASE, PAGE_SIZE, MAP_CACHED);
      

FatFs on Linux side

Linux can provide a file system to Erika with the help of the FatFs library which can be built for Linux as well. To build the library for Linux just use the following commands:

      :~ mkdir fatfs-linux-build
      :~ aarch64-linux-gnu-gcc -DFATFS_LINUX -I /full/erika3/path/contrib/fatfs/diskio/memory/ -I /full/FatFs/path/source/ 
                                                -c /full/erika3/path/contrib/fatfs/diskio/memory/*.c 
                                                /full/FatFs/path/source/ff.c /full/FatFs/path/source/ffsystem.c 
                                                /full/FatFs/path/source/ffunicode.c 
       :~ aarch64-linux-gnu-ar rcs libfatfs.a *.o

Now that library is built, you can edit a main.c which looks similar to the one provided with the FatFs Erika demo. FatFs functions are the same indeed (except for the handling of system time which is correctly taken from Linux time). The main difference with the Erika application is in the shared memory's mapping which is performed with mmap in order to be accessed by the application. A code snippet which performs such mapping could be the following:

       long int physical_address = 0x274800000;
       size_t memory_size = MINIMUM_FAT_SIZE;
       void *process_memory_address = NULL;
       int fd = open("/dev/mem", O_RDWR);
       if(fd >= 0 && physical_address && size){
               process_memory_address = mmap(NULL, memory_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 
                       physical_address);
        }

After calling this function with proper parameters, the application must init the fmem drive with f_mem_init(process_memory_address, memory_size) and then create/modify the FAT file system (use f_mkfs, f_mount and friends...).

Link your main with the library:

      :~ aarch64-linux-gnu-gcc  -I /full/erika3/path/contrib/fatfs/diskio/memory/ -I /full/FatFs/path/source/ 
                                                -c main.c -L/full/path/fatfs-linux-build -lfatfs


First execute the Linux application and then the Erika inmate. The latter will show all the directories/files you decided to create.