Ignore:
Timestamp:
Jun 18, 2017, 10:06:41 PM (5 years ago)
Author:
alain
Message:

Introduce syscalls.

File:
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/kernel/vfs/fatfs.c

    r15 r23  
    22 * fatfs.c - FATFS file system API implementation.
    33 *
    4  * Author    Mohamed Lamine Karaoui (2015)
    5  *           Alain Greiner (2016)
     4 * Author    Mohamed Lamine Karaoui (2014,2015)
     5 *           Alain Greiner (2016,2017)
    66 *
    77 * Copyright (c) UPMC Sorbonne Universites
     
    3232#include <rpc.h>
    3333#include <mapper.h>
     34#include <cluster.h>
    3435#include <dev_ioc.h>
    3536#include <fatfs.h>
    3637
    37 
    3838//////////////////////////////////////////////////////////////////////////////////////////
     39//          Extern  variables         
     40//////////////////////////////////////////////////////////////////////////////////////////
     41
     42extern vfs_ctx_t        fs_context[FS_TYPES_NR];   // allocated in vfs.c file
     43
     44extern remote_barrier_t global_barrier;            // allocated dans kernel_init.c
     45 
    3946//////////////////////////////////////////////////////////////////////////////////////////
    4047// FATFS specific functions : these functions cannot be called by the VFS
    4148//////////////////////////////////////////////////////////////////////////////////////////
    42 //////////////////////////////////////////////////////////////////////////////////////////
    4349
    4450//////////////////////////////////////////////////////////
     
    4652                                        uint32_t      cluster )
    4753{
    48     return (ctx->cluster_begin_lba + ((cluster - 2) * ctx->sectors_per_cluster));
     54    return (ctx->cluster_begin_lba + ((cluster - 2) << 3));
    4955}
    5056
     
    95101
    96102}  // end fatfs_get_cluster()
     103
     104///////////////////////////////////////////////////////////////////////////////////////
     105// This static function return an integer record value (one, two, or four bytes)
     106// from a memory buffer, taking into account endianness.
     107///////////////////////////////////////////////////////////////////////////////////////
     108// @ offset        : first byte of record in buffer.
     109// @ size          : record length in bytes (1/2/4).
     110// @ buffer        : pointer on buffer base.
     111// @ little endian : the most significant byte has the highest address when true.
     112// @ return the integer value in a 32 bits word.
     113///////////////////////////////////////////////////////////////////////////////////////
     114static uint32_t get_record_from_buffer( uint32_t    offset,
     115                                        uint32_t    size,
     116                                        uint8_t   * buffer,
     117                                        uint32_t    little_endian )
     118{
     119    uint32_t n;
     120    uint32_t res  = 0;
     121
     122    if ( little_endian)
     123    {
     124        for( n = size ; n > 0 ; n-- ) res = (res<<8) | buffer[offset+n-1];
     125    }
     126    else
     127    {
     128        for( n = 0 ; n < size ; n++ ) res = (res<<8) | buffer[offset+n];
     129    }
     130    return res;
     131
     132}  // end get_record_from_buffer()
     133
    97134
    98135
     
    162199
    163200///////////////////////////////////////////////////////////////////////////////////////
     201//          The following functions are called by the VFS.
    164202///////////////////////////////////////////////////////////////////////////////////////
    165 // Generic API : the following functions are called by the VFS,
    166 //               and must be defined by all isupported file systems.
    167 ///////////////////////////////////////////////////////////////////////////////////////
    168 ///////////////////////////////////////////////////////////////////////////////////////
    169 
    170 ////////////////////////////////////////////////////////////
    171 error_t fatfs_inode_create( struct vfs_inode_s * vfs_inode )
    172 {
    173     printk("\n[PANIC] %s not fully implemented yet\n", __FUNCTION__ );
    174     hal_core_sleep();
    175 
     203
     204
     205///////////////////
     206xptr_t fatfs_init()
     207{
     208    kmem_req_t    req;
     209    fatfs_ctx_t * fatfs_ctx;       // local pointer on FATFS context
     210    vfs_ctx_t   * vfs_ctx;         // local pointer on VFS context
     211    xptr_t        root_inode_xp;   // extended pointer on root inode
     212    error_t       error;
     213
     214    // get local pointer on VFS context for FATFS
     215    vfs_ctx = &fs_context[FS_TYPE_FATFS];
     216
     217    // get number of kernel instances and extended pointer on global barrier
     218    cluster_t * cluster     = LOCAL_CLUSTER;
     219    uint32_t    nb_clusters = cluster->x_size * cluster->y_size;
     220    xptr_t      barrier_xp  = XPTR( cluster->io_cxy , &global_barrier );
     221
     222    ///// step 1 : all clusters allocate memory for FATFS context
     223
     224    // allocate memory for FATFS context extension
     225        req.type    = KMEM_FATFS_CTX;
     226        req.size    = sizeof(fatfs_ctx_t);
     227    req.flags   = AF_KERNEL | AF_ZERO;
     228        fatfs_ctx   = (fatfs_ctx_t *)kmem_alloc( &req );
     229
     230    if( fatfs_ctx == NULL )
     231    {
     232        printk("\n[PANIC] in %s : no memory for FATFS context\n", __FUNCTION__ );
     233        hal_core_sleep();
     234    }
     235   
     236    ///// step 2 : only cluster_0 access device and creates root inode
     237
     238    if( local_cxy == 0 )
     239    {
     240        // create VFS root inode
     241        error = vfs_inode_create( XPTR_NULL,        // no parent dentry
     242                                  FS_TYPE_FATFS,
     243                                  INODE_TYPE_DIR,
     244                                  0,                // attr
     245                                  0,                // rights
     246                                  0,                // uid
     247                                  0,                // gid
     248                                  &root_inode_xp );
     249
     250        assert( (error == 0 ) , __FUNCTION__ , "cannot create VFS root inode" );
     251
     252        // initialize VFS context / access device to initialize FATFS context
     253        error = fatfs_ctx_init( vfs_ctx,
     254                                fatfs_ctx,
     255                                root_inode_xp );
     256
     257        // create FATFS root inode
     258        error = fatfs_inode_create( GET_PTR( root_inode_xp ) ,
     259                                    fatfs_ctx->root_dir_cluster );
     260
     261        if( error )
     262        {
     263            printk("\n[PANIC] in %s : cannot create FATFS root inode\n", __FUNCTION__ );
     264            hal_core_sleep();
     265        }
     266
     267    }
     268
     269    //////////////// synchronize all clusters
     270    remote_barrier( barrier_xp , nb_clusters );
     271
     272    ///// step 3 : all others clusters initialize both context and extension
     273
     274    if( local_cxy != 0 )
     275    {
     276        // copy VFS context from remote cluster_0 to local cluster
     277        hal_remote_memcpy( XPTR( local_cxy , vfs_ctx ),
     278                           XPTR( 0 , vfs_ctx ),
     279                           sizeof(vfs_ctx_t) );
     280
     281        // copy FATFS context from remote cluster_0 to local cluster
     282        hal_remote_memcpy( XPTR( local_cxy , fatfs_ctx ),
     283                           XPTR( 0 , vfs_ctx->extend ) ,
     284                           sizeof(fatfs_ctx_t) );
     285
     286        // update extend field in local copy of VFS context
     287        vfs_ctx->extend = fatfs_ctx;
     288    }
     289
     290    return root_inode_xp;
     291
     292}  // end fatfs_init()
     293
     294//////////////////////////////////////////////
     295error_t fatfs_ctx_init( vfs_ctx_t   * vfs_ctx,
     296                        fatfs_ctx_t * fatfs_ctx,
     297                        xptr_t        root_inode_xp )
     298{
     299    error_t  error;
     300    uint8_t  buffer[512];    // buffer for boot record
     301
     302    // make a synchronous access to IOC device to read the boot record from device
     303    error = dev_ioc_sync_read( buffer , 0 , 1 );
     304    assert( (error == 0) , __FUNCTION__ , "cannot access FAT boot record" );
     305
     306    // check sector size from boot record
     307    uint32_t sector_size = get_record_from_buffer( BPB_BYTSPERSEC , buffer , 1 );
     308    assert( (sector_size == 512) , __FUNCTION__ , "sector size must be 512 bytes" );
     309
     310    // check cluster size from boot record
     311    uint32_t nb_sectors = get_record_from_buffer( BPB_SECPERCLUS , buffer , 1 );
     312    assert( (nb_sectors == 8) , __FUNCTION__ , "cluster size must be 8 sectors" );
     313
     314    // check number of FAT copies from boot record
     315    uint32_t nb_fats = get_record_from_buffer( BPB_NUMFATS , buffer , 1 );
     316    assert( (nb_fats == 1) , __FUNCTION__ , "number of FAT copies must be 1" );
     317
     318    // get & check number of sectors in FAT from boot record
     319    uint32_t fat_sectors = get_record_from_buffer( BPB_FAT32_FATSZ32 , buffer , 1 );
     320    assert( ((fat_sectors & 0xF) == 0) , __FUNCTION__ , "FAT not multiple of 16 sectors");
     321
     322    // get and check root cluster from boot record
     323    uint32_t root_cluster = get_record_from_buffer( BPB_FAT32_ROOTCLUS , buffer , 1 );
     324    assert( (root_cluster == 2) , __FUNCTION__ , "Root cluster index must be  2");
     325
     326    // get FAT lba from boot record
     327    uint32_t fat_lba = get_record_from_buffer( BPB_RSVDSECCNT , buffer , 1 );
     328   
     329    // allocate a mapper for the FAT itself
     330    mapper_t * fat_mapper = mapper_create();
     331    assert( (fat_mapper != NULL) , __FUNCTION__ , "no memory for FAT mapper" );
     332
     333    // initialize the FATFS context
     334    fatfs_ctx->fat_begin_lba         = fat_lba;
     335    fatfs_ctx->fat_sectors_count     = fat_sectors;
     336    fatfs_ctx->bytes_per_sector      = sector_size;
     337    fatfs_ctx->bytes_per_cluster     = sector_size * nb_sectors;
     338    fatfs_ctx->cluster_begin_lba     = fat_lba + fat_sectors;
     339    fatfs_ctx->root_dir_cluster      = 2;
     340    fatfs_ctx->last_allocated_sector = 0;    // TODO ???
     341    fatfs_ctx->last_allocated_index  = 0;    // TODO ???
     342    fatfs_ctx->fat_mapper_xp         = XPTR( local_cxy , fat_mapper );
     343
     344    // initialize the VFS context
     345    vfs_ctx->type    = FS_TYPE_FATFS;
     346    vfs_ctx->attr    = 0;                    // not READ_ONLY / not SYNC
     347    vfs_ctx->count   = fat_sectors << 10;    // total number of sectors in data region
     348    vfs_ctx->blksize = 512;                  // number of bytes per sector
     349    vfs_ctx->root_xp = root_inode_xp;
     350    vfs_ctx->extend  = fatfs_ctx;
     351
     352    spinlock_init( &vfs_ctx->lock );
     353
     354    bitmap_init( vfs_ctx->bitmap , CONFIG_VFS_MAX_INODES );
     355
     356    return 0;
     357
     358}  // end fatfs_ctx_init()
     359 
     360
     361
     362////////////////////////////////////////////////////
     363void fatfs_ctx_destroy( struct vfs_ctx_s * vfs_ctx )
     364{
     365    kmem_req_t    req;
     366    fatfs_ctx_t * fatfs_ctx;
     367
     368    // get pointer on FATFS context extension
     369    fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend;
     370
     371    req.type = KMEM_FATFS_INODE;
     372    req.ptr  = fatfs_ctx;
     373    kmem_free( &req );
     374}
     375
     376
     377////////////////////////////////////////////////////
     378error_t fatfs_inode_create( vfs_inode_t * vfs_inode,
     379                            uint32_t      first_cluster )
     380{
    176381    kmem_req_t      req;
    177382    fatfs_inode_t * fatfs_inode;
    178383
    179     // allocate memory for fatfs inode
     384    // allocate memory for FATFS inode extension
    180385        req.type    = KMEM_FATFS_INODE;
    181386        req.size    = sizeof(fatfs_inode_t);
     
    185390    if( fatfs_inode == NULL ) return ENOMEM;
    186391
    187     // initialise ramfs_inode
    188     fatfs_inode->first_cluster = 0;   // TODO ???
    189     fatfs_inode->ctx           = (fatfs_ctx_t *)vfs_inode->ctx->extend;
     392    // link FATFS inode to VFS inode
     393    vfs_inode->extend = fatfs_inode;
     394
     395    // initialise FATFS inode
     396    fatfs_inode->first_cluster = first_cluster;
    190397 
    191     // link fatfs_inode to vfs_inode
    192     vfs_inode->extend = fatfs_inode;
    193 
    194398    return 0;
    195 
    196 }
    197 
    198 //////////////////////////////////////////////////////
    199 void fatfs_inode_destroy( struct vfs_inode_s * inode )
    200 {
    201     printk("\n[PANIC] %s not fully implemented yet\n", __FUNCTION__ );
    202     hal_core_sleep();
    203 }
    204 
    205 //////////////////////////////////////////////////
    206 error_t fatfs_ctx_create( struct vfs_ctx_s * ctx )
    207 {
    208     printk("\n[PANIC] %s not fully implemented yet\n", __FUNCTION__ );
    209     hal_core_sleep();
    210 
    211     return 0;
    212 }
    213 
    214 ////////////////////////////////////////////////
    215 void fatfs_ctx_destroy( struct vfs_ctx_s * ctx )
    216 {
    217     printk("\n[PANIC] %s not fully implemented yet\n", __FUNCTION__ );
    218     hal_core_sleep();
    219 }
     399}
     400
     401///////////////////////////////////////////////////
     402void fatfs_inode_destroy( vfs_inode_t * vfs_inode )
     403{
     404    kmem_req_t      req;
     405    fatfs_inode_t * fatfs_inode;
     406
     407    // get pointer on FATFS inode
     408    fatfs_inode = (fatfs_inode_t *)vfs_inode->extend;
     409
     410    req.type = KMEM_FATFS_INODE;
     411    req.ptr  = fatfs_inode;
     412    kmem_free( &req );
     413
     414        vfs_inode->extend = NULL;
     415}
     416
    220417
    221418////////////////////////////////////////////////
     
    223420                                  bool_t   is_read )
    224421{
    225     // get source buffer base address
    226     char * buffer = (char *)ppm_page2base( page );
     422    // get memory buffer base address
     423    uint8_t * buffer = (uint8_t *)ppm_page2base( page );
    227424 
    228425    // get pointer on source mapper and page index from page descriptor
    229     mapper_t * src_mapper  = page->mapper;
     426    mapper_t * mapper      = page->mapper;
    230427    uint32_t   page_index  = page->index;
    231428
    232     if( src_mapper == NULL)
    233     {
    234         printk("\n[PANIC] in %s : no mapper for this page\n", __FUNCTION__ );
    235         hal_core_sleep();
    236     }
    237 
    238429    // get VFS inode pointer from mapper
    239     vfs_inode_t * vfs_inode = src_mapper->inode;
     430    vfs_inode_t * vfs_inode = mapper->inode;
    240431
    241432    // get FATFS inode pointer for VFS inode
     
    246437
    247438    // get FATFS context pointer from FATFS inode
    248     fatfs_ctx_t * fatfs_ctx = fatfs_inode->ctx;
     439    fatfs_ctx_t * fatfs_ctx = (fatfs_ctx_t *)vfs_inode->ctx->extend;
    249440
    250441    // get number of sectors
Note: See TracChangeset for help on using the changeset viewer.