Changeset 23 for trunk/kernel/vfs/fatfs.c
- Timestamp:
- Jun 18, 2017, 10:06:41 PM (7 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/vfs/fatfs.c
r15 r23 2 2 * fatfs.c - FATFS file system API implementation. 3 3 * 4 * Author Mohamed Lamine Karaoui (201 5)5 * Alain Greiner (2016 )4 * Author Mohamed Lamine Karaoui (2014,2015) 5 * Alain Greiner (2016,2017) 6 6 * 7 7 * Copyright (c) UPMC Sorbonne Universites … … 32 32 #include <rpc.h> 33 33 #include <mapper.h> 34 #include <cluster.h> 34 35 #include <dev_ioc.h> 35 36 #include <fatfs.h> 36 37 37 38 38 ////////////////////////////////////////////////////////////////////////////////////////// 39 // Extern variables 40 ////////////////////////////////////////////////////////////////////////////////////////// 41 42 extern vfs_ctx_t fs_context[FS_TYPES_NR]; // allocated in vfs.c file 43 44 extern remote_barrier_t global_barrier; // allocated dans kernel_init.c 45 39 46 ////////////////////////////////////////////////////////////////////////////////////////// 40 47 // FATFS specific functions : these functions cannot be called by the VFS 41 48 ////////////////////////////////////////////////////////////////////////////////////////// 42 //////////////////////////////////////////////////////////////////////////////////////////43 49 44 50 ////////////////////////////////////////////////////////// … … 46 52 uint32_t cluster ) 47 53 { 48 return (ctx->cluster_begin_lba + ((cluster - 2) * ctx->sectors_per_cluster));54 return (ctx->cluster_begin_lba + ((cluster - 2) << 3)); 49 55 } 50 56 … … 95 101 96 102 } // 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 /////////////////////////////////////////////////////////////////////////////////////// 114 static 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 97 134 98 135 … … 162 199 163 200 /////////////////////////////////////////////////////////////////////////////////////// 201 // The following functions are called by the VFS. 164 202 /////////////////////////////////////////////////////////////////////////////////////// 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 /////////////////// 206 xptr_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 ////////////////////////////////////////////// 295 error_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 //////////////////////////////////////////////////// 363 void 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 //////////////////////////////////////////////////// 378 error_t fatfs_inode_create( vfs_inode_t * vfs_inode, 379 uint32_t first_cluster ) 380 { 176 381 kmem_req_t req; 177 382 fatfs_inode_t * fatfs_inode; 178 383 179 // allocate memory for fatfs inode384 // allocate memory for FATFS inode extension 180 385 req.type = KMEM_FATFS_INODE; 181 386 req.size = sizeof(fatfs_inode_t); … … 185 390 if( fatfs_inode == NULL ) return ENOMEM; 186 391 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; 190 397 191 // link fatfs_inode to vfs_inode192 vfs_inode->extend = fatfs_inode;193 194 398 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 /////////////////////////////////////////////////// 402 void 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 220 417 221 418 //////////////////////////////////////////////// … … 223 420 bool_t is_read ) 224 421 { 225 // get sourcebuffer base address226 char * buffer = (char*)ppm_page2base( page );422 // get memory buffer base address 423 uint8_t * buffer = (uint8_t *)ppm_page2base( page ); 227 424 228 425 // get pointer on source mapper and page index from page descriptor 229 mapper_t * src_mapper= page->mapper;426 mapper_t * mapper = page->mapper; 230 427 uint32_t page_index = page->index; 231 428 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 238 429 // get VFS inode pointer from mapper 239 vfs_inode_t * vfs_inode = src_mapper->inode;430 vfs_inode_t * vfs_inode = mapper->inode; 240 431 241 432 // get FATFS inode pointer for VFS inode … … 246 437 247 438 // 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; 249 440 250 441 // get number of sectors
Note: See TracChangeset
for help on using the changeset viewer.