Changeset 265 for trunk/kernel
- Timestamp:
- Jul 21, 2017, 7:36:08 AM (7 years ago)
- Location:
- trunk/kernel
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/kern/kernel_init.c
r249 r265 860 860 fatfs_ctx_t * fatfs_ctx = fatfs_ctx_alloc(); 861 861 862 printk("\n@@@ %s extend = %x\n", __FUNCTION__ , fatfs_ctx );863 864 862 nolock_assert( (fatfs_ctx != NULL) , __FUNCTION__ , 865 863 "cannot create FATFS context in cluster 0\n" ); … … 901 899 hal_core_sleep(); 902 900 } 903 904 ///////////////////////////////@@@905 fatfs_ctx_display();906 ///////////////////////////////@@@907 901 908 902 // register VFS root inode in process_zero -
trunk/kernel/kern/rpc.c
r248 r265 74 74 &rpc_kcm_alloc_server, // 22 75 75 &rpc_kcm_free_server, // 23 76 &rpc_mapper_move_ server,// 2476 &rpc_mapper_move_buffer_server, // 24 77 77 &rpc_undefined, // 25 78 78 &rpc_undefined, // 26 … … 1184 1184 1185 1185 ///////////////////////////////////////////////////////////////////////////////////////// 1186 // [24] Marshaling functions attached to RPC_MAPPER_MOVE 1187 ///////////////////////////////////////////////////////////////////////////////////////// 1188 1189 /////////////////////////////////////////// 1190 void rpc_mapper_move_client( cxy_t cxy, 1191 mapper_t * mapper, // in 1192 uint32_t to_buffer, // in 1193 uint32_t file_offset, // in 1194 void * buffer, // in 1195 uint32_t size, // in 1196 error_t * error ) // out 1197 { 1198 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 1199 1200 // initialise RPC descriptor header 1201 rpc_desc_t rpc; 1202 rpc.index = RPC_MAPPER_MOVE; 1186 // [24] Marshaling functions attached to RPC_MAPPER_MOVE_BUFFER 1187 ///////////////////////////////////////////////////////////////////////////////////////// 1188 1189 /////////////////////////////////////////////////// 1190 void rpc_mapper_move_buffer_client( cxy_t cxy, 1191 mapper_t * mapper, // in 1192 bool_t to_buffer, // in 1193 bool_t is_user, // in 1194 uint32_t file_offset, // in 1195 void * buffer, // in 1196 uint32_t size, // in 1197 error_t * error ) // out 1198 { 1199 assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n"); 1200 1201 // initialise RPC descriptor header 1202 rpc_desc_t rpc; 1203 rpc.index = RPC_MAPPER_MOVE_BUFFER; 1203 1204 rpc.response = 1; 1204 1205 … … 1206 1207 rpc.args[0] = (uint64_t)(intptr_t)mapper; 1207 1208 rpc.args[1] = (uint64_t)to_buffer; 1208 rpc.args[2] = (uint64_t)file_offset; 1209 rpc.args[3] = (uint64_t)(intptr_t)buffer; 1210 rpc.args[4] = (uint64_t)size; 1209 rpc.args[2] = (uint64_t)is_user; 1210 rpc.args[3] = (uint64_t)file_offset; 1211 rpc.args[4] = (uint64_t)(intptr_t)buffer; 1212 rpc.args[5] = (uint64_t)size; 1211 1213 1212 1214 // register RPC request in remote RPC fifo (blocking function) … … 1214 1216 1215 1217 // get output values from RPC descriptor 1216 *error = (error_t)rpc.args[ 5];1217 } 1218 1219 //////////////////////////////////////// 1220 void rpc_mapper_move_ server( xptr_t xp )1218 *error = (error_t)rpc.args[6]; 1219 } 1220 1221 /////////////////////////////////////////////// 1222 void rpc_mapper_move_buffer_server( xptr_t xp ) 1221 1223 { 1222 1224 mapper_t * mapper; 1223 uint32_t to_buffer; 1225 bool_t to_buffer; 1226 bool_t is_user; 1224 1227 uint32_t file_offset; 1225 1228 void * buffer; … … 1234 1237 mapper = (mapper_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) ); 1235 1238 to_buffer = hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) ); 1236 file_offset = hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) ); 1237 buffer = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) ); 1238 size = hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) ); 1239 is_user = hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) ); 1240 file_offset = hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) ); 1241 buffer = (void *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[4] ) ); 1242 size = hal_remote_lwd( XPTR( client_cxy , &desc->args[5] ) ); 1239 1243 1240 1244 // call local kernel function 1241 error = mapper_move( mapper, 1242 to_buffer, 1243 file_offset, 1244 buffer, 1245 size ); 1245 error = mapper_move_buffer( mapper, 1246 to_buffer, 1247 is_user, 1248 file_offset, 1249 buffer, 1250 size ); 1246 1251 1247 1252 // set output argument to client RPC descriptor 1248 hal_remote_swd( XPTR( client_cxy , &desc->args[ 5] ) , (uint64_t)error );1253 hal_remote_swd( XPTR( client_cxy , &desc->args[6] ) , (uint64_t)error ); 1249 1254 } 1250 1255 -
trunk/kernel/kern/rpc.h
r238 r265 79 79 RPC_KCM_ALLOC = 22, 80 80 RPC_KCM_FREE = 23, 81 RPC_MAPPER_MOVE 81 RPC_MAPPER_MOVE_BUFFER = 24, 82 82 83 83 RPC_MAX_INDEX = 30, … … 551 551 552 552 /*********************************************************************************** 553 * [24] The RPC_MAPPER_MOVE is called by the vfs_move() function.553 * [24] The RPC_MAPPER_MOVE_USER is called by the vfs_move() function. 554 554 * It allows a client thread to requires a remote mapper to move data to/from 555 555 * an user buffer, as specified by the arguments. … … 558 558 * @ mapper : [in] local pointer on mapper 559 559 * @ to_buffer : [in] move data from buffer to mapper if non zero. 560 * @ is_user : [in] buffer in user space if non zero. 560 561 * @ file_offset : [in] first byte to move in mapper 561 562 * @ buffer : [in] pointer on buffer in user space … … 563 564 * @ error : [out] error status (0 if success). 564 565 **********************************************************************************/ 565 void rpc_mapper_move_client( cxy_t cxy, 566 struct mapper_s * mapper, 567 uint32_t to_buffer, 568 uint32_t file_offset, 569 void * buffer, 570 uint32_t size, 571 error_t * error ); 572 573 void rpc_mapper_move_server( xptr_t xp ); 566 void rpc_mapper_move_buffer_client( cxy_t cxy, 567 struct mapper_s * mapper, 568 bool_t to_buffer, 569 bool_t is_user, 570 uint32_t file_offset, 571 void * buffer, 572 uint32_t size, 573 error_t * error ); 574 575 void rpc_mapper_move_buffer_server( xptr_t xp ); 574 576 575 577 -
trunk/kernel/libk/elf.c
r227 r265 87 87 88 88 // load .elf header 89 count = vfs_move( true , 89 count = vfs_move( true, // to_buffer 90 false, // is_user 90 91 file_xp, 91 92 buffer, … … 94 95 if( count != size ) 95 96 { 96 printk("\n[ERROR] in %s : failed to read ELF header\n", __FUNCTION__ ); 97 printk("\n[ERROR] in %s : cannot read ELF header size : %d / done = %d\n", 98 __FUNCTION__ , size , count ); 97 99 return -1; 98 100 } … … 231 233 error_t error; 232 234 233 elf_dmsg("\n[INFO] %s : enter for %s\n", __FUNCTION__ , pathname );235 elf_dmsg("\n[INFO] %s : enters for <%s>\n", __FUNCTION__ , pathname ); 234 236 235 237 // avoid GCC warning … … 250 252 } 251 253 252 elf_dmsg("\n[INFO] %s : file %sopen\n", __FUNCTION__ , pathname );254 elf_dmsg("\n[INFO] %s : file <%s> open\n", __FUNCTION__ , pathname ); 253 255 254 256 // load header in local buffer … … 301 303 302 304 // load seg descriptors array to local buffer 303 count = vfs_move( true, 305 count = vfs_move( true, // to_buffer 306 false, // is_user 304 307 file_xp, 305 308 segs_base, -
trunk/kernel/mm/mapper.c
r246 r265 169 169 if ( page == NULL ) // missing page => create it and load it from file system 170 170 { 171 mapper_dmsg("\n[INFO] %s : missing page => load from FS\n", __FUNCTION__ );171 mapper_dmsg("\n[INFO] %s : missing page => load from device\n", __FUNCTION__ ); 172 172 173 173 // allocate one page from PPM … … 298 298 } // end mapper_release_page() 299 299 300 ///////////////////////////////////////// 301 error_t mapper_move( mapper_t * mapper, 302 bool_t to_buffer, 303 uint32_t file_offset, 304 void * buffer, 305 uint32_t size ) 300 //////////////////////////////////////////////// 301 error_t mapper_move_buffer( mapper_t * mapper, 302 bool_t to_buffer, 303 bool_t is_user, 304 uint32_t file_offset, 305 void * buffer, 306 uint32_t size ) 306 307 { 307 308 uint32_t page_offset; // first byte to move to/from a mapper page … … 313 314 uint8_t * buf_ptr; // current buffer address 314 315 315 mapper_dmsg("\n[INFO] %s : enter / to_buf = %d / buffer = %x\n",316 mapper_dmsg("\n[INFO] %s : enters / to_buf = %d / buffer = %x\n", 316 317 __FUNCTION__ , to_buffer , buffer ); 317 318 … … 339 340 else page_count = CONFIG_PPM_PAGE_SIZE; 340 341 342 mapper_dmsg("\n[INFO] %s : index = %d / offset = %d / count = %d\n", 343 __FUNCTION__ , index , page_offset , page_count ); 344 341 345 // get page descriptor 342 346 page = mapper_get_page( mapper , index ); … … 350 354 buf_ptr = (uint8_t *)buffer + done; 351 355 356 mapper_dmsg("\n[INFO] %s : index = %d / buf_ptr = %x / map_ptr = %x\n", 357 __FUNCTION__ , index , buf_ptr , map_ptr ); 358 352 359 // move fragment 353 360 if( to_buffer ) 354 361 { 355 hal_copy_to_uspace( buf_ptr , map_ptr , page_count ); 356 } 357 else 362 if( is_user ) hal_copy_to_uspace( buf_ptr , map_ptr , page_count ); 363 else memcpy( buf_ptr , map_ptr , page_count ); 364 } 365 else 358 366 { 359 367 page_do_dirty( page ); 360 hal_copy_from_uspace( map_ptr , buf_ptr , page_count ); 368 if( is_user ) hal_copy_from_uspace( map_ptr , buf_ptr , page_count ); 369 else memcpy( map_ptr , buf_ptr , page_count ); 361 370 } 362 371 … … 369 378 return 0; 370 379 371 } // end mapper_move ()372 380 } // end mapper_move_buffer() 381 -
trunk/kernel/mm/mapper.h
r246 r265 51 51 * - The mapper_get_page() function that return a page descriptor pointer from a page 52 52 * index in file is in charge of handling the miss on the mapper cache. 53 * - The vfs_mapper_move_page() function is used to handle miss on one specific page,53 * - The vfs_mapper_move_page() function access the file system to handle a mapper miss, 54 54 * or update a dirty page on device. 55 * - The vfs_mapper_load_all() functions is used to load all pages of a given directory56 * into the mapper.57 * - the mapper_move () function is used to move data to or from an user buffer.55 * - The vfs_mapper_load_all() functions is used to load all pages of a given file 56 * or directory into the mapper. 57 * - the mapper_move_user() function is used to move data to or from an user buffer. 58 58 * This user space buffer can be physically distributed in several clusters. 59 59 * - In the present implementation the cache size for a given file increases on demand, … … 117 117 118 118 /******************************************************************************************* 119 * This function move data between a kernel mapper and an userbuffer.119 * This function move data between a mapper and an user or kernel buffer. 120 120 * It must be called by a thread running in the cluster containing the mapper. 121 * It split the data in fragments : one fragment is a set of contiguous bytes 122 * stored in the same mapper page. 123 * It uses "hal_uspace" accesses to move fragments to/from the user buffer. 121 * - A kernel buffer must be entirely contained in the same cluster as the mapper. 122 * - An user buffer can be physically distributed in several clusters. 123 * In both cases, the data transfer is split in "fragments": one fragment contains 124 * contiguous bytes in the same mapper page. 125 * - It uses "hal_uspace" accesses to move a fragment to/from the user buffer. 126 * - It uses a simple memcpy" access to move a fragment to/from a kernel buffer. 124 127 * In case of write, the dirty bit is set for all pages written in the mapper. 125 128 * The offset in the file descriptor is not modified by this function. 126 129 ******************************************************************************************* 127 * @ mapper : local pointer on local mapper. 128 * @ to_buffer : move data from mapper to buffer if true. 130 * @ mapper : local pointer on mapper. 131 * @ to_buffer : mapper -> buffer if true / buffer -> mapper if false. 132 * @ is_user : user space buffer if true / kernel local buffer if false. 129 133 * @ file_offset : first byte to move in file. 130 * @ buffer : bufferaddress in user space.134 * @ buffer : pointer on buffer (local kernel buffer or user spaceaddress in user space. 131 135 * @ size : number of bytes to move. 132 136 * returns O if success / returns EINVAL if error. 133 137 ******************************************************************************************/ 134 error_t mapper_move( mapper_t * mapper, 135 bool_t to_buffer, 136 uint32_t file_offset, 137 void * buffer, 138 uint32_t size ); 138 error_t mapper_move_buffer( mapper_t * mapper, 139 bool_t to_buffer, 140 bool_t is_user, 141 uint32_t file_offset, 142 void * buffer, 143 uint32_t size ); 139 144 140 145 /******************************************************************************************* -
trunk/kernel/syscalls/sys_read.c
r124 r265 110 110 111 111 // transfer nbytes to kernel buffer 112 error = vfs_move( true, // read => (to_buffer = true) 112 error = vfs_move( true, // to_buffer 113 true, // is_user 113 114 file_xp , 114 115 kbuf , -
trunk/kernel/syscalls/sys_write.c
r124 r265 110 110 111 111 // transfer nbytes from kernel buffer 112 error = vfs_move( false, // write => (to_buffer = false) 112 error = vfs_move( false, // from buffer 113 true, // is_user 113 114 file_xp, 114 115 kbuf , -
trunk/kernel/vfs/fatfs.c
r246 r265 46 46 47 47 ////////////////////////////////////////////////////////////////////////////////////////// 48 // FATFS privateand static functions48 // FATFS specific and static functions 49 49 ////////////////////////////////////////////////////////////////////////////////////////// 50 50 … … 74 74 75 75 ////////////////////////////////////////////////////////////////////////////////////////// 76 // This function display the content of the FATFS context. 76 // This function return an integer record value (one, two, or four bytes) 77 // from a memory buffer, taking into account endianness. 78 ////////////////////////////////////////////////////////////////////////////////////////// 79 // @ offset : first byte of record in buffer. 80 // @ size : record length in bytes (1/2/4). 81 // @ buffer : pointer on buffer base. 82 // @ little endian : the most significant byte has the highest address when true. 83 // @ return the integer value in a 32 bits word. 84 ////////////////////////////////////////////////////////////////////////////////////////// 85 static uint32_t fatfs_get_record( uint32_t offset, 86 uint32_t size, 87 uint8_t * buffer, 88 uint32_t little_endian ) 89 { 90 uint32_t n; 91 uint32_t res = 0; 92 93 if ( little_endian) 94 { 95 for( n = size ; n > 0 ; n-- ) res = (res<<8) | buffer[offset+n-1]; 96 } 97 else 98 { 99 for( n = 0 ; n < size ; n++ ) res = (res<<8) | buffer[offset+n]; 100 } 101 return res; 102 103 } // end fatfs_get_record() 104 105 ////////////////////////////////////////////////////////////////////////////////////////// 106 // This static function retun in the <name> buffer a short name stored in 107 // a SFN FATFS directory entry. 108 /////////////////////////i//////////////////////////////////////////////////////////////// 109 // @ buffer : pointer on buffer containing the directory entry. 110 // @ name : [out] buffer allocated by the caller. 111 ////////////////////////////////////////////////////////////////////////////////////////// 112 static void fatfs_get_name_from_short( uint8_t * buffer, 113 char * name ) 114 { 115 uint32_t i; 116 uint32_t j = 0; 117 118 // get name 119 for ( i = 0; i < 8 && buffer[i] != ' '; i++ ) 120 { 121 name[j] = to_lower( buffer[i] ); 122 j++; 123 } 124 125 // get extension 126 for ( i = 8; i < 8 + 3 && buffer[i] != ' '; i++ ) 127 { 128 // we entered the loop so there is an extension. add the dot 129 if ( i == 8 ) 130 { 131 name[j] = '.'; 132 j++; 133 } 134 135 name[j] = to_lower( buffer[i] ); 136 j++; 137 } 138 139 name[j] = '\0'; 140 } 141 142 ////////////////////////////////////////////////////////////////////////////////////////// 143 // This static function retun in the <name> buffer a partial name stored in 144 // a LFN FATFS directory entry. 145 /////////////////////////i//////////////////////////////////////////////////////////////// 146 // @ buffer : pointer on buffer containing the directory entry. 147 // @ name : [out] buffer allocated by the caller. 148 ////////////////////////////////////////////////////////////////////////////////////////// 149 static void fatfs_get_name_from_long( uint8_t * buffer, 150 char * name ) 151 { 152 uint32_t name_offset = 0; 153 uint32_t buffer_offset = get_length(LDIR_ORD); 154 uint32_t l_name_1 = get_length(LDIR_NAME_1); 155 uint32_t l_name_2 = get_length(LDIR_NAME_2); 156 uint32_t l_name_3 = get_length(LDIR_NAME_3); 157 uint32_t l_attr = get_length(LDIR_ATTR); 158 uint32_t l_type = get_length(LDIR_TYPE); 159 uint32_t l_chksum = get_length(LDIR_CHKSUM); 160 uint32_t l_rsvd = get_length(LDIR_RSVD); 161 162 uint32_t j = 0; 163 uint32_t eof = 0; 164 165 while ( (buffer_offset != DIR_ENTRY_SIZE) && (!eof) ) 166 { 167 while (j != l_name_1 && !eof ) 168 { 169 if ( (buffer[buffer_offset] == 0x00) || 170 (buffer[buffer_offset] == 0xFF) ) 171 { 172 eof = 1; 173 continue; 174 } 175 name[name_offset] = buffer[buffer_offset]; 176 buffer_offset += 2; 177 j += 2; 178 name_offset++; 179 } 180 181 buffer_offset += (l_attr + l_type + l_chksum); 182 j = 0; 183 184 while (j != l_name_2 && !eof ) 185 { 186 if ( (buffer[buffer_offset] == 0x00) || 187 (buffer[buffer_offset] == 0xFF) ) 188 { 189 eof = 1; 190 continue; 191 } 192 name[name_offset] = buffer[buffer_offset]; 193 buffer_offset += 2; 194 j += 2; 195 name_offset++; 196 } 197 198 buffer_offset += l_rsvd; 199 j = 0; 200 201 while (j != l_name_3 && !eof ) 202 { 203 if ( (buffer[buffer_offset] == 0x00) || 204 (buffer[buffer_offset] == 0xFF) ) 205 { 206 eof = 1; 207 continue; 208 } 209 name[name_offset] = buffer[buffer_offset]; 210 buffer_offset += 2; 211 j += 2; 212 name_offset++; 213 } 214 } 215 name[name_offset] = 0; 216 217 } // end get_name_from_long() 218 219 ////////////////////////////////////////////////////////////////////////////////////////// 220 // This function returns the FATFS cluster index of a page identified by its page 221 // index in the file, using the FAT mapper. It scans the FAT mapper, starting from the 222 // FATFS cluster index allocated to the first page of the file, until it reaches the 223 // searched page. The FAT mapper is automatically updated in case of miss. 224 // This function can be called by any thread running in any cluster, as it uses the 225 // RPC_FATFS_GET_CLUSTER to access the remote FAT mapper if required. 226 // We use a RPC to scan the FAT because the RPC_FIFO will avoid contention 227 // in the cluster containing the FAT mapper, and the RPC latency is not critical 228 // compared to the device access latency. 229 ////////////////////////////////////////////////////////////////////////////////////////// 230 // @ ctx : pointer on local FATFS context. 231 // @ first_cluster : first cluster allocated to a file in FATFS. 232 // @ page_index : index of searched page in file (one page occupies one cluster). 233 // @ cluster_index : [out] pointer on buffer for FATFS cluster index. 234 // @ return 0 if success / return EIO if a FAT cluster miss cannot be solved. 235 ////////////////////////////////////////////////////////////////////////////////////////// 236 static error_t fatfs_cluster_from_index( fatfs_ctx_t * ctx, 237 uint32_t first_cluster, 238 uint32_t page_index, 239 uint32_t * cluster_index ) 240 { 241 uint32_t searched_cluster; // searched FATFS cluster index 242 error_t error; 243 244 // get extended pointer on FAT mapper 245 xptr_t fat_mapper_xp = ctx->fat_mapper_xp; 246 247 // get cluster cxy and local pointer on FAT mapper 248 cxy_t fat_mapper_cxy = GET_CXY( fat_mapper_xp ); 249 mapper_t * fat_mapper_ptr = (mapper_t *)GET_PTR( fat_mapper_xp ); 250 251 if( fat_mapper_cxy == local_cxy ) // FAT mapper is local 252 { 253 error = fatfs_get_cluster( fat_mapper_ptr, 254 first_cluster, 255 page_index, 256 &searched_cluster ); 257 } 258 else // FAT mapper is remote 259 { 260 rpc_fatfs_get_cluster_client( fat_mapper_cxy, 261 fat_mapper_ptr, 262 first_cluster, 263 page_index, 264 &searched_cluster, 265 &error ); 266 } 267 268 if( error ) 269 { 270 printk("\n[ERROR] in %s : cannot access FAT\n", __FUNCTION__ ); 271 return error; 272 } 273 274 // return success 275 *cluster_index = searched_cluster; 276 return 0; 277 278 } // end fatfs_cluster_from_index() 279 280 ////////////////////////////////////////////////////////////////////////////////////////// 281 // FATFS specific but extern functions 282 ////////////////////////////////////////////////////////////////////////////////////////// 283 77 284 ////////////////////////////////////////////////////////////////////////////////////////// 78 285 void fatfs_ctx_display() 79 286 { 80 uint32_t type = FS_TYPE_FATFS;81 287 vfs_ctx_t * vfs_ctx = &fs_context[FS_TYPE_FATFS]; 82 288 fatfs_ctx_t * fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend; … … 99 305 } 100 306 101 //////////////////////////////////////////////////////////////////////////////////////////102 // This function return an integer record value (one, two, or four bytes)103 // from a memory buffer, taking into account endianness.104 //////////////////////////////////////////////////////////////////////////////////////////105 // @ offset : first byte of record in buffer.106 // @ size : record length in bytes (1/2/4).107 // @ buffer : pointer on buffer base.108 // @ little endian : the most significant byte has the highest address when true.109 // @ return the integer value in a 32 bits word.110 //////////////////////////////////////////////////////////////////////////////////////////111 static uint32_t fatfs_get_record( uint32_t offset,112 uint32_t size,113 uint8_t * buffer,114 uint32_t little_endian )115 {116 uint32_t n;117 uint32_t res = 0;118 119 if ( little_endian)120 {121 for( n = size ; n > 0 ; n-- ) res = (res<<8) | buffer[offset+n-1];122 }123 else124 {125 for( n = 0 ; n < size ; n++ ) res = (res<<8) | buffer[offset+n];126 }127 return res;128 129 } // end fatfs_get_record()130 131 //////////////////////////////////////////////////////////////////////////////////////////132 // This static function retun in the <name> buffer a short name stored in133 // a SFN FATFS directory entry.134 /////////////////////////i////////////////////////////////////////////////////////////////135 // @ buffer : pointer on buffer containing the directory entry.136 // @ name : [out] buffer allocated by the caller.137 //////////////////////////////////////////////////////////////////////////////////////////138 static void fatfs_get_name_from_short( uint8_t * buffer,139 char * name )140 {141 uint32_t i;142 uint32_t j = 0;143 144 // get name145 for ( i = 0; i < 8 && buffer[i] != ' '; i++ )146 {147 name[j] = to_lower( buffer[i] );148 j++;149 }150 151 // get extension152 for ( i = 8; i < 8 + 3 && buffer[i] != ' '; i++ )153 {154 // we entered the loop so there is an extension. add the dot155 if ( i == 8 )156 {157 name[j] = '.';158 j++;159 }160 161 name[j] = to_lower( buffer[i] );162 j++;163 }164 165 name[j] = '\0';166 }167 168 //////////////////////////////////////////////////////////////////////////////////////////169 // This static function retun in the <name> buffer a partial name stored in170 // a LFN FATFS directory entry.171 /////////////////////////i////////////////////////////////////////////////////////////////172 // @ buffer : pointer on buffer containing the directory entry.173 // @ name : [out] buffer allocated by the caller.174 //////////////////////////////////////////////////////////////////////////////////////////175 static void fatfs_get_name_from_long( uint8_t * buffer,176 char * name )177 {178 uint32_t name_offset = 0;179 uint32_t buffer_offset = get_length(LDIR_ORD);180 uint32_t l_name_1 = get_length(LDIR_NAME_1);181 uint32_t l_name_2 = get_length(LDIR_NAME_2);182 uint32_t l_name_3 = get_length(LDIR_NAME_3);183 uint32_t l_attr = get_length(LDIR_ATTR);184 uint32_t l_type = get_length(LDIR_TYPE);185 uint32_t l_chksum = get_length(LDIR_CHKSUM);186 uint32_t l_rsvd = get_length(LDIR_RSVD);187 188 uint32_t j = 0;189 uint32_t eof = 0;190 191 while ( (buffer_offset != DIR_ENTRY_SIZE) && (!eof) )192 {193 while (j != l_name_1 && !eof )194 {195 if ( (buffer[buffer_offset] == 0x00) ||196 (buffer[buffer_offset] == 0xFF) )197 {198 eof = 1;199 continue;200 }201 name[name_offset] = buffer[buffer_offset];202 buffer_offset += 2;203 j += 2;204 name_offset++;205 }206 207 buffer_offset += (l_attr + l_type + l_chksum);208 j = 0;209 210 while (j != l_name_2 && !eof )211 {212 if ( (buffer[buffer_offset] == 0x00) ||213 (buffer[buffer_offset] == 0xFF) )214 {215 eof = 1;216 continue;217 }218 name[name_offset] = buffer[buffer_offset];219 buffer_offset += 2;220 j += 2;221 name_offset++;222 }223 224 buffer_offset += l_rsvd;225 j = 0;226 227 while (j != l_name_3 && !eof )228 {229 if ( (buffer[buffer_offset] == 0x00) ||230 (buffer[buffer_offset] == 0xFF) )231 {232 eof = 1;233 continue;234 }235 name[name_offset] = buffer[buffer_offset];236 buffer_offset += 2;237 j += 2;238 name_offset++;239 }240 }241 name[name_offset] = 0;242 243 } // end get_name_from_long()244 245 //////////////////////////////////////////////////////////////////////////////////////////246 // This function returns the FATFS cluster index of a page identified by its page247 // index in the file, using the FAT mapper. It scans the FAT mapper, starting from the248 // FATFS cluster index allocated to the first page of the file, until it reaches the249 // searched page. The FAT mapper is automatically updated in case of miss.250 // This function can be called by any thread running in any cluster, as it uses the251 // RPC_FATFS_GET_CLUSTER to access the remote FAT mapper if required.252 // We use a RPC to scan the FAT because the RPC_FIFO will avoid contention253 // in the cluster containing the FAT mapper, and the RPC latency is not critical254 // compared to the device access latency.255 //////////////////////////////////////////////////////////////////////////////////////////256 // @ ctx : pointer on local FATFS context.257 // @ first_cluster : first cluster allocated to a file in FATFS.258 // @ page_index : index of searched page in file (one page occupies one cluster).259 // @ cluster_index : [out] pointer on buffer for FATFS cluster index.260 // @ return 0 if success / return EIO if a FAT cluster miss cannot be solved.261 //////////////////////////////////////////////////////////////////////////////////////////262 static error_t fatfs_cluster_from_index( fatfs_ctx_t * ctx,263 uint32_t first_cluster,264 uint32_t page_index,265 uint32_t * cluster_index )266 {267 uint32_t searched_cluster; // searched FATFS cluster index268 error_t error;269 270 // get extended pointer on FAT mapper271 xptr_t fat_mapper_xp = ctx->fat_mapper_xp;272 273 // get cluster cxy and local pointer on FAT mapper274 cxy_t fat_mapper_cxy = GET_CXY( fat_mapper_xp );275 mapper_t * fat_mapper_ptr = (mapper_t *)GET_PTR( fat_mapper_xp );276 277 if( fat_mapper_cxy == local_cxy ) // FAT mapper is local278 {279 error = fatfs_get_cluster( fat_mapper_ptr,280 first_cluster,281 page_index,282 &searched_cluster );283 }284 else // FAT mapper is remote285 {286 rpc_fatfs_get_cluster_client( fat_mapper_cxy,287 fat_mapper_ptr,288 first_cluster,289 page_index,290 &searched_cluster,291 &error );292 }293 294 if( error )295 {296 printk("\n[ERROR] in %s : cannot access FAT\n", __FUNCTION__ );297 return error;298 }299 300 // return success301 *cluster_index = searched_cluster;302 return 0;303 304 } // end fatfs_cluster_from_index()305 306 //////////////////////////////////////////////////////////////////////////////////////////307 // FATFS specific but extern function (used by RPC_FATFS_GET_CLUSTER)308 //////////////////////////////////////////////////////////////////////////////////////////309 310 307 ///////////////////////////////////////////// 311 308 error_t fatfs_get_cluster( mapper_t * mapper, 312 uint32_t first_cluster ,313 uint32_t searched_page,314 uint32_t * cluster)309 uint32_t first_cluster_id, 310 uint32_t page_index, 311 uint32_t * searched_cluster_id ) 315 312 { 316 313 page_t * current_page_desc; // pointer on current page descriptor … … 319 316 uint32_t current_page_offset; // offset of slot in current page 320 317 uint32_t page_count_in_file; // index of page in file (index in linked list) 321 uint32_t current_cluster; // content of current FAT slot 322 323 fatfs_dmsg("\n[INFO] %s : enters / first_cluster_id = %d / searched_page = %d\n", 324 __FUNCTION__ , first_cluster , searched_page ); 325 326 #if CONFIG_FATFS_DEBUG 318 uint32_t current_cluster_id; // content of current FAT slot 319 320 assert( (page_index > 0) , __FUNCTION__ , "no FAT access required for first page\n"); 321 322 fatfs_dmsg("\n[INFO] %s : enters / mapper = %x / first_cluster_id = %d / page_index = %d\n", 323 __FUNCTION__ , first_cluster_id , page_index ); 324 325 #if (CONFIG_FATFS_DEBUG > 1) 327 326 uint32_t * buf = (uint32_t *)ppm_page2vaddr( mapper_get_page ( mapper , 0 ) ); 328 327 uint32_t line , word; 329 printk("\n*** FAT content for first 128entries ***\n");330 for( line = 0 ; line < 8; line++ )331 { 332 printk("% d : ");328 printk("\n*** FAT mapper content for first 256 entries ***\n"); 329 for( line = 0 ; line < 16 ; line++ ) 330 { 331 printk("%X : ", line ); 333 332 for( word = 0 ; word < 16 ; word++ ) printk("%X ", buf[(line<<4) + word] ); 334 333 printk("\n"); … … 340 339 341 340 // initialize loop variable 342 current_page_index = first_cluster / slots_per_page;343 current_page_offset = first_cluster % slots_per_page;341 current_page_index = first_cluster_id / slots_per_page; 342 current_page_offset = first_cluster_id % slots_per_page; 344 343 page_count_in_file = 0; 345 344 346 345 // scan FAT (i.e. traverse FAT linked list) 347 while( page_count_in_file <= searched_page)346 while( page_count_in_file <= page_index ) 348 347 { 349 348 … … 360 359 361 360 // get FAT slot content 362 current_cluster = current_page_buffer[current_page_offset];361 current_cluster_id = current_page_buffer[current_page_offset]; 363 362 364 363 // update loop variables 365 current_page_index = current_cluster / slots_per_page;366 current_page_offset = current_cluster % slots_per_page;364 current_page_index = current_cluster_id / slots_per_page; 365 current_page_offset = current_cluster_id % slots_per_page; 367 366 page_count_in_file++; 368 367 } 369 368 370 369 fatfs_dmsg("\n[INFO] %s : exit / cluster_id = %d\n", 371 __FUNCTION__ , current_cluster );372 373 * cluster = current_cluster;370 __FUNCTION__ , current_cluster_id ); 371 372 *searched_cluster_id = current_cluster_id; 374 373 return 0; 375 374 … … 550 549 else // it is a normal inode mapper 551 550 { 552 // get first cluster index from inode extension 553 uint32_t first_cluster = (uint32_t)(intptr_t)inode->extend; 554 555 fatfs_dmsg("\n[INFO] %s : for inode %x / first cluster_id = %d\n", 556 __FUNCTION__ , inode , first_cluster ); 557 558 // compute FATFS_cluster index for the accessed page 559 uint32_t cluster = 0; 560 error_t error = fatfs_cluster_from_index( fatfs_ctx, 561 first_cluster, 562 index, 563 &cluster ); 564 if( error ) return EIO; 565 566 // get lba from cluster 567 uint32_t lba = fatfs_lba_from_cluster( fatfs_ctx , cluster ); 551 uint32_t searched_cluster_id; 552 553 // get first_cluster_id from inode extension 554 uint32_t first_cluster_id = (uint32_t)(intptr_t)inode->extend; 555 556 fatfs_dmsg("\n[INFO] %s : for inode %x / first_cluster_id = %d\n", 557 __FUNCTION__ , inode , first_cluster_id ); 558 559 // compute cluster_id 560 if( index == 0 ) // no need to access FAT mapper 561 { 562 searched_cluster_id = first_cluster_id; 563 } 564 else // FAT mapper access required 565 { 566 // get cluster and local pointer on FAT mapper 567 xptr_t fat_mapper_xp = fatfs_ctx->fat_mapper_xp; 568 cxy_t fat_mapper_cxy = GET_CXY( fat_mapper_xp ); 569 mapper_t * fat_mapper_ptr = (mapper_t *)GET_PTR( fat_mapper_xp ); 570 571 // access FAT mapper 572 if( fat_mapper_cxy == local_cxy ) // FAT mapper is local 573 { 574 error = fatfs_get_cluster( fat_mapper_ptr, 575 first_cluster_id, 576 index, 577 &searched_cluster_id ); 578 } 579 else // FAT mapper is remote 580 { 581 rpc_fatfs_get_cluster_client( fat_mapper_cxy, 582 fat_mapper_ptr, 583 first_cluster_id, 584 index, 585 &searched_cluster_id, 586 &error ); 587 } 588 589 if( error ) return EIO; 590 } 591 592 // get lba from cluster_id 593 uint32_t lba = fatfs_lba_from_cluster( fatfs_ctx , searched_cluster_id ); 568 594 569 595 fatfs_dmsg("\n[INFO] %s : for inode %x / page = %d / cluster_id = %d / lba = %x\n", 570 __FUNCTION__ , inode , index , cluster, lba );596 __FUNCTION__ , inode , index , searched_cluster_id , lba ); 571 597 572 598 // access device … … 584 610 } // end fatfs_mapper_move_page() 585 611 586 ///////////////////////////////////////////////////// ////////////612 ///////////////////////////////////////////////////// 587 613 error_t fatfs_inode_load( vfs_inode_t * parent_inode, 588 614 char * name, … … 629 655 // get page base 630 656 base = ppm_page2vaddr( page ); 657 658 #if (CONFIG_FATFS_DEBUG > 1) 659 uint32_t * buf = (uint32_t *)base; 660 uint32_t line , word; 661 printk("\n*** DIRECTORY content for first 16 entries ***\n"); 662 for( line = 0 ; line < 16 ; line++ ) 663 { 664 printk("%X : ", line ); 665 for( word = 0 ; word < 8 ; word++ ) printk("%X ", buf[(line<<4) + word] ); 666 printk("\n"); 667 } 668 #endif 669 631 670 632 671 // scan this page until end of directory, end of page, or name found -
trunk/kernel/vfs/fatfs.h
r246 r265 183 183 184 184 ////////////////////////////////////////////////////////////////////////////////////////// 185 // FATFS specific but public functions (used by RPC)185 // FATFS specific extern functions 186 186 ////////////////////////////////////////////////////////////////////////////////////////// 187 187 188 188 /****************************************************************************************** 189 * This staticfunction scan the FAT (File Allocation Table), stored in the FAT mapper,189 * This function scan the FAT (File Allocation Table), stored in the FAT mapper, 190 190 * and returns the FATFS cluster index for a given page of a given file. 191 191 * It must be called by a thread running in the cluster containing the FAT mapper. 192 * We can use a RPC to scan the remote FAT mapper, because the RPC_FIFO will avoid 193 * contention in the cluster containing the FAT mapper, and the RPC latency is not 194 * critical compared to the device access latency. 192 195 * The FAT is actually an array of uint32_t slots. Each slot in this array contains the 193 196 * index of another slot in this array, to form one linked list for each file stored on … … 198 201 * automatically updates the FAT mapper from informations stored on device in case of miss. 199 202 ****************************************************************************************** 200 * @ mapper : local pointer on the FAT mapper.201 * @ first_cluster : index of the first FATFS cluster allocated to the file.202 * @ searched_page : index of searched page in the file.203 * @ cluster : [out] pointer on buffer for thefound FATFS cluster index.204 * @ return 0 if success / return EIO if FAT mapper miss cannot be solved.203 * @ mapper : local pointer on the FAT mapper. 204 * @ first_cluster_id : index of the first FATFS cluster allocated to the file. 205 * @ searched_page : index of searched page in the file. 206 * @ searched_cluster_id : [out] found FATFS cluster index. 207 * @ return 0 if success / return EIO if a FAT mapper miss cannot be solved. 205 208 *****************************************************************************************/ 206 209 error_t fatfs_get_cluster( struct mapper_s * mapper, 207 210 uint32_t first_cluster, 208 uint32_t searched_page, 209 uint32_t * cluster ); 210 211 211 uint32_t page_index, 212 uint32_t * searched_cluster_id ); 213 214 /****************************************************************************************** 215 * This function display the content of the FATFS context. 216 *****************************************************************************************/ 217 void fatfs_ctx_display(); 212 218 213 219 -
trunk/kernel/vfs/vfs.c
r246 r265 640 640 if( error ) return error; 641 641 642 vfs_dmsg("\n[INFO] %s exit for %s/ file_id = %d / file_xp = %l / at cycle %d\n",642 vfs_dmsg("\n[INFO] %s : exit for <%s> / file_id = %d / file_xp = %l / at cycle %d\n", 643 643 __FUNCTION__ , path , file_id , file_xp , hal_get_cycles() ); 644 644 … … 652 652 ///////////////////////////////////// 653 653 error_t vfs_move( bool_t to_buffer, 654 bool_t is_user, 654 655 xptr_t file_xp, 655 656 void * buffer, … … 682 683 if( file_cxy == local_cxy ) 683 684 { 684 error = mapper_move( mapper, 685 to_buffer, 686 file_offset, 687 buffer, 688 size ); 685 error = mapper_move_buffer( mapper, 686 to_buffer, 687 is_user, 688 file_offset, 689 buffer, 690 size ); 689 691 } 690 692 else 691 693 { 692 rpc_mapper_move_client( file_cxy, 693 mapper, 694 to_buffer, 695 file_offset, 696 buffer, 697 size, 698 &error ); 694 rpc_mapper_move_buffer_client( file_cxy, 695 mapper, 696 to_buffer, 697 is_user, 698 file_offset, 699 buffer, 700 size, 701 &error ); 699 702 } 700 703 701 return error; 702 } 703 else if (inode_type == INODE_TYPE_DIR ) 704 { 705 printk("\n[ERROR] in %s : inode is a directory", __FUNCTION__ ); 706 return EINVAL; 707 } 708 else if (inode_type == INODE_TYPE_DEV ) 709 { 710 // TODO [AG] 711 return 0; 712 } 713 else 714 { 715 printk("\n[PANIC] in %s : illegal inode type\n", __FUNCTION__ ); 716 hal_core_sleep(); 704 if( error ) return -1; 705 else return size; 706 } 707 else 708 { 709 printk("\n[ERROR] in %s : inode is not a file", __FUNCTION__ ); 717 710 return -1; 718 711 } … … 1377 1370 vfs_inode_unlock( parent_xp ); 1378 1371 1379 vfs_dmsg("\n[INFO] in %s : exit / %sfound / inode = %l\n",1372 vfs_dmsg("\n[INFO] in %s : exit <%s> found / inode = %l\n", 1380 1373 __FUNCTION__ , pathname , child_xp ); 1381 1374 … … 1609 1602 error_t vfs_mapper_load_all( vfs_inode_t * inode ) 1610 1603 { 1611 assert( (inode != NULL) , __FUNCTION__ , " page pointer is NULL\n" );1604 assert( (inode != NULL) , __FUNCTION__ , "inode pointer is NULL\n" ); 1612 1605 1613 1606 uint32_t index; … … 1617 1610 uint32_t size = inode->size; 1618 1611 1619 assert( (mapper != NULL) , __FUNCTION__ , "no mapper for page\n" ); 1620 1621 assert( (size != 0) , __FUNCTION__ , "size cannot be 0\n"); 1612 assert( (mapper != NULL) , __FUNCTION__ , "mapper pointer is NULL\n" ); 1622 1613 1623 1614 uint32_t npages = size >> CONFIG_PPM_PAGE_SHIFT; 1624 if( size & CONFIG_PPM_PAGE_MASK) npages++;1625 1626 // loop on allpages1615 if( (size & CONFIG_PPM_PAGE_MASK) || (size == 0) ) npages++; 1616 1617 // loop on pages 1627 1618 for( index = 0 ; index < npages ; index ++ ) 1628 1619 { -
trunk/kernel/vfs/vfs.h
r239 r265 725 725 /****************************************************************************************** 726 726 * This function moves <size> bytes between the file identified by the open file descriptor 727 * <file_xp> and a local kernel <buffer> , taken into account the offset in <file_xp>. 727 * <file_xp> and a local kernel or user <buffer>, as defined by the <is_user> argument, 728 * and taken into account the offset in <file_xp>. 728 729 * The transfer direction is defined by the <to_buffer> argument. 729 730 ****************************************************************************************** 730 * @ to_buffer : mapper -> buffer if true / buffer->mapper if false. 731 * @ to_buffer : mapper -> buffer if true / buffer -> mapper if false. 732 * @ is_user : user space buffer if true / local kernel buffer if false. 731 733 * @ file_xp : extended pointer on the remote file descriptor. 732 * @ buffer : local pointer on local kernelbuffer.734 * @ buffer : local pointer on buffer. 733 735 * @ size : requested number of bytes from offset. 734 736 * @ returns number of bytes actually transfered / -1 if error. 735 737 *****************************************************************************************/ 736 738 error_t vfs_move( bool_t to_buffer, 739 bool_t is_user, 737 740 xptr_t file_xp, 738 741 void * buffer,
Note: See TracChangeset
for help on using the changeset viewer.