00001 
00002 #include "routix/system.h"
00003 #include "string.h"
00004 #include "drivers/fat.h"
00005 #include "routix/paging.h"
00006 #include "routix/kalloc.h"
00007 #include <routix/kstdio.h>
00008 #include <routix/file.h>
00009 #include <drivers/floppy.h>
00010 #include <fs/blockcache.h>
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 #define ERR_NOMEM       -1      //No hay memoria suficiente (kmalloc_page==NULL)
00020 #define ERR_NO_FAT      -2
00021 #define ERR_NO_BOOT     -3
00022 #define ERR_LAST_SECTOR -5
00023 #define LAST_SECTOR     -100    //Ultimo sector
00024 
00025 
00026 
00027 byte buffer[512];
00028 
00029 
00030 dev_fat_t dev_fat[1];           
00031 
00032 
00034 
00035 
00037 int fat_12(void)
00038 {
00039     dev_fat[0].boot_leido = FALSE;
00040     dev_fat[0].fat_levantada = FALSE;
00041 
00042     
00043                 
00044     if ( CACHE_READ(fd0,BOOTSECTOR,buffer) == -1)       {
00045                         kprintf("No se pudo leer sector\n");
00046                         return -1;
00047                 }
00048 
00049     boot_sector_t *p= (boot_sector_t *) buffer;
00050     
00051     dev_fat[0].fat_size = p->BPB_FATSz16;
00052     dev_fat[0].cantidad_de_fats = p->BPB_NumFATs;
00053     dev_fat[0].sectores_ocultos = p->BPB_HiddSec;
00054     dev_fat[0].sectores_totales = p->BPB_TotSec16;
00055     dev_fat[0].root_dir_size = (p->BPB_RootEntCnt * sizeof(fat12_entry_t)) / SECTOR_SIZE;
00056     dev_fat[0].sectores_por_cluster = p->BPB_SecPerClus;
00057     dev_fat[0].sector_size = p->BPB_BytsPerSec;
00058     dev_fat[0].fat_start = 1;       
00059     dev_fat[0].root_dir_start = 1 + dev_fat[0].sectores_ocultos + (dev_fat[0].cantidad_de_fats * dev_fat[0].fat_size);
00060     
00061     dev_fat[0].boot_leido=TRUE;
00062     return OK;
00063 }
00064 
00066 
00067 
00069 
00070 fat_t fat_header;   
00071 
00072 int levantar_fat(void)
00073 {
00074     
00075 
00076     
00077     
00078     word fat_paginas = (dev_fat[0].fat_size * BLOQUE_SIZE) / PAGINA_SIZE;
00079 
00080     
00081     
00082     word sec_fat_levantados=0;
00083     word i, j;
00084 
00085     if ( dev_fat[0].boot_leido == FALSE ) {
00086         kprintf("Debe levantarse el BOOT\n");
00087         return ERR_NO_BOOT;
00088     }
00089 
00090     if ( dev_fat[0].fat_levantada == TRUE ) {
00091         return OK;
00092     }
00093 
00094     
00095     
00096     if ( (dev_fat[0].fat_size * BLOQUE_SIZE) % PAGINA_SIZE)
00097         fat_paginas++;
00098 
00099     
00100     
00101     fat_t *aux= &fat_header;
00102     aux->bloque = NULL;
00103     aux->next = NULL;
00104 
00105     for(i=0 ; i < fat_paginas ; i++) {
00106     
00107         
00108         if (!(aux->bloque = (byte *) kmalloc_page()))   {
00109             kprintf("No hay memoria disponible para levantar la FAT\n");
00110             return ERR_NOMEM;
00111         }
00112 
00113         
00114         
00115         kmapmem((addr_t) aux->bloque, DIR_FAT_VIRTUAL + (i * PAGINA_SIZE), KERNEL_PDT, PAGE_PRES | PAGE_SUPER | PAGE_RW); 
00116         aux->bloque = (byte *) (DIR_FAT_VIRTUAL + (i * PAGINA_SIZE));
00117 
00118         
00119         for(j=0;(j<((PAGINA_SIZE/BLOQUE_SIZE))) && (sec_fat_levantados<dev_fat[0].fat_size);j++, sec_fat_levantados++ ) {
00120             
00121                 if (CACHE_READ(fd0,sec_fat_levantados + dev_fat[0].fat_start, aux->bloque) == -1 ) {
00122                         kprintf("No se pudo levantar la FAT");
00123                         return -1;
00124                 }
00125     
00126           aux->next = (fat_t *) malloc( sizeof(fat_t) );
00127                 aux->next->bloque = aux->bloque + BLOQUE_SIZE;
00128                 aux = aux->next;
00129                 aux->next = NULL;
00130         }
00131     }
00132 
00133     
00134     dev_fat[0].fat_levantada = TRUE;
00135     return OK;
00136 }
00137 
00138 
00139 
00140 
00141 
00142 int init_floppy_fs(void)
00143 {
00144     dev_fat[0].fat_start = 1;
00145     if ( (fat_12()!=OK) || (levantar_fat()!=OK) )
00146         return -1;
00147 
00148     return OK;
00149 }       
00150 
00151 
00152 
00153 
00154 
00155 
00156 void fat_adapta_name (byte *nombre_fat, byte *adaptado)
00157 {
00158     byte x=0,z;
00159     strcpy(adaptado,"            ");
00160     for( z=0  ; z<11 ;  z++) {
00161         if ( (z==8) && (nombre_fat[8]!=' ') ) {
00162             adaptado[x]='.';
00163             x++;
00164         }
00165         adaptado[x] = nombre_fat[z];
00166         if (nombre_fat[z] != ' ')
00167             x++;
00168     }
00169     adaptado[x]='\0';
00170     
00171 }       
00172 
00173 
00174 
00175 
00177 
00178 
00180 int fat_next_sector ( dword sector )
00181 {
00182     
00183     if (dev_fat[0].fat_levantada==FALSE)
00184         return ERR_NO_FAT;
00185 
00186     if (sector == 0xfff)
00187         return ERR_LAST_SECTOR;
00188 
00189     sector -= 31;       
00190     
00191     
00192     
00193     byte lsb, msb;
00194 
00195     word indice; 
00196 
00197     indice = (sector * 3) >> 1;
00198     lsb = fat_header.bloque[indice];
00199     msb = fat_header.bloque[indice + 1];
00200 
00201     word proximo_sector;
00202 
00203     if (sector % 2)         
00204         proximo_sector = (((msb << 8) | lsb) & 0xfff0) >> 4;
00205     
00206     else                            
00207         proximo_sector = ((msb << 8) | lsb) & 0x0fff;
00208         
00209     if ( proximo_sector==0xFFF )
00210         return LAST_SECTOR;
00211     
00212     return (proximo_sector + 31);
00213 }       
00214 
00215 
00216 
00217 
00218 
00219 
00220 int str_dir_len (char *nombre)
00221 {
00222     int len=0;
00223     while( *nombre++ != '/') {
00224         len++;
00225         if ( (len > 12) || (*nombre=='\0') )
00226             return -1;
00227     }
00228 
00229     return len;     
00230 }       
00231 
00232 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00245 
00246 fat12_entry_t *fat_file_find (char *nombre, fat12_entry_t *datos_archivo)
00247 {
00248 
00249     char nombre_aux[MAX_PATH_LEN];    
00250     char nombre_archivos[MAX_PATH_LEN];    
00251     
00252     byte x; 
00253     
00254     byte root_dir_flag=TRUE;   
00255     
00256     
00257     str_to_upper(nombre);
00258 
00259     
00260     dword dir_sector, dir_size;
00261     
00262     
00263     dir_sector = dev_fat[0].root_dir_start;
00264     dir_size = dev_fat[0].root_dir_size;
00265     
00266     int dir_len;    
00267                     
00268 
00269     fat12_entry_t *aux_fat;     
00270 kprintf("1 Mallocs: %d\tFrees: %d\n", num_mallocs, num_frees);
00271     
00272     do {
00273 fat_file_find_break:
00274         if ((dir_len=str_dir_len(nombre)) > 0)  {           
00275                 strncpy(nombre_aux, nombre, dir_len);       
00276                 nombre = nombre + dir_len + 1;
00277                 }
00278                 else strcpy(nombre_aux, nombre);                    
00279 
00280                 do {
00281 kprintf("2 Mallocs: %d\tFrees: %d\n", num_mallocs, num_frees);
00282                         
00283                         if ( CACHE_READ(fd0,dir_sector, buffer) == -1 ) {
00284                                 kprintf("No se puede leer sector\n");
00285                                 return NULL;
00286                 }
00287 kprintf("3 Mallocs: %d\tFrees: %d\n", num_mallocs, num_frees);
00288 
00289                 aux_fat = (fat12_entry_t *) buffer;
00290 
00291 
00292                 
00293                 for( x=0 ; x < (SECTOR_SIZE / sizeof(fat12_entry_t)) ; x++) {   
00294                                 fat_adapta_name( aux_fat->nombre , nombre_archivos);
00295 
00296                         if ( strcmp( nombre_archivos, nombre_aux)==0 ) {        
00297                                     if (dir_len < 0) {
00298                                         memcpy( datos_archivo, aux_fat, sizeof(fat12_entry_t));
00299                                                 return aux_fat;
00300                                 }
00301                                 dir_sector = aux_fat->sector + 31;
00302                                 dir_size = 0xffff;
00303                                 root_dir_flag=FALSE;    
00304                                 goto fat_file_find_break;
00305                                 }
00306                                 aux_fat++;
00307                 }
00308                 if (root_dir_flag==TRUE) {
00309                                 dir_sector++;
00310                                 if (dir_sector > (dev_fat[0].root_dir_start + dev_fat[0].root_dir_size) )
00311                                 return NULL;
00312                 }
00313                 else {
00314                                 if ((dir_sector = fat_next_sector(dir_sector))==LAST_SECTOR)
00315                                         return NULL;
00316                 }       
00317 
00318                 } while (dir_sector != LAST_SECTOR);
00319 
00320     }while ( dir_len > 0 ); 
00321 
00322     
00323     return NULL;
00324 }
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 
00333 
00334 
00335 
00336 
00337 struct floppy_cache *header_floppy_cache=NULL;
00338 
00339 dword sectores_cache=0;
00340 
00341 
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 
00354 void floppy_cache_init (void)
00355 {
00356 
00357         return; 
00358 
00359         
00360 
00361 
00362 
00363 
00364 
00365 
00366 }
00367 
00368 
00369 
00370 
00371 
00372 
00373 
00374 
00375 
00376 
00377 
00378 
00379 
00380 
00381 
00382 
00383 
00384 
00385 
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394 
00395 
00396 
00397 
00398 
00399 
00400 
00401 
00402 
00403 
00404 
00405 
00406 
00407 
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 
00418 
00419 
00420 
00421 
00422 
00423 
00424 
00426 
00427 
00428 
00429 
00430 
00431 
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 
00441 
00442 
00443 
00444 
00445 
00446 
00447 
00448 
00449 
00450 
00451 
00452 
00453 
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 
00465 
00466 
00467 
00468 
00469 
00470 
00471 
00472 
00473 
00474 
00475 
00476 
00477 
00478 
00479 
00480 
00481 
00482 
00483 
00484 
00485 
00486 
00487 
00488 
00489 
00490 
00491 void print_fat_info (void)
00492 {
00493     putchar('\n');
00494     boot_sector_t *p= (boot_sector_t *) buffer;
00495 
00496     if ( p->BPB_RsvdSecCnt != 1)
00497         kprintf("Filesystem no reconocido\n");
00498     else kprintf("Disco es FAT12\n");
00499 
00500     byte i;
00501     kprintf("BS_FilSysType:");
00502     for(i=0; i<8;i++)
00503         putchar(p->BS_FilSysType[i]);
00504     putchar('\n');
00505 
00506     kprintf("Sectores por FAT: %d\n", dev_fat[0].fat_size);
00507     kprintf("Cantidad de FATs: %d\n", dev_fat[0].cantidad_de_fats);
00508     kprintf("Fat start: %d\n", dev_fat[0].fat_start);
00509     kprintf("Sectores ocultos: %d\n", dev_fat[0].sectores_ocultos);
00510     kprintf("Sectores totales: %d\n", dev_fat[0].sectores_totales);
00511     kprintf("Sectores por Cluster: %d\n", dev_fat[0].sectores_por_cluster);
00512     kprintf("Sectores asignados al directorio root: %d\n", dev_fat[0].root_dir_size);
00513     kprintf("Comienzo del root dir: sector %d\n", dev_fat[0].root_dir_start);
00514 }       
00515 
00516 
00518 
00520 void fat_root_dir (void)
00521 {       
00522     if ((dev_fat[0].boot_leido==FALSE) || (dev_fat[0].fat_levantada==FALSE) )
00523         if ( init_floppy_fs() != OK ) {
00524             kprintf("No se puede leer disco\n");
00525         }
00526     
00527     byte root_dir_sector;
00528     byte x;
00529     fat12_entry_t *datos;
00530 
00531     char nombre[MAX_PATH_LEN];
00532     
00533     for (root_dir_sector=dev_fat[0].root_dir_start;root_dir_sector<(dev_fat[0].root_dir_start+dev_fat[0].root_dir_size) \
00534     ; root_dir_sector++) {
00535         
00536         if ( CACHE_READ(fd0,root_dir_sector, buffer) == -1 ) {
00537             kprintf("No se puede leer sector\n");
00538             return;
00539         }
00540         datos = (fat12_entry_t *) buffer;
00541     
00542         for( x=0 ; x < (SECTOR_SIZE / sizeof(fat12_entry_t)) ; x++) {   
00543             if ((datos->nombre[0]!=FAT_EMPTY) && (datos->nombre[0]!=FAT_SUBDIR) && \
00544                             (datos->nombre[0]!=FAT_DELETED)) {
00545                 fat_adapta_name( datos->nombre , nombre);
00546                 kprintf("Archivo: %s\n", nombre);
00547             }   
00548             datos++;
00549         }
00550     }    
00551 }
00552 
00554 
00556 void fat_test(void)
00557 {
00558 
00559     if ((dev_fat[0].boot_leido==FALSE) || (dev_fat[0].fat_levantada==FALSE) )
00560         if ( init_floppy_fs() != OK ) {
00561             kprintf("No se puede leer disco\n");
00562         }
00563 
00564     byte nombre[25];
00565     fat12_entry_t datos_archivo;
00566     kprintf("Archivo a buscar:");
00567     gets(nombre);
00568     if ( fat_file_find (nombre, &datos_archivo) ) {
00569         kprintf("Tamaņo: %d\n", datos_archivo.size);
00570 
00571         if (datos_archivo.atributo & 0x10)
00572             kprintf("El archivo es un Directorio\n");
00573         
00574         kprintf("Comienza en Cluster: %d\n", \
00575         (datos_archivo.sector * dev_fat[0].sectores_por_cluster) + dev_fat[0].root_dir_start + dev_fat[0].root_dir_size -2); 
00576     }
00577     else {
00578         kprintf("Archivo no encontrado: %s\n", nombre);
00579         return;
00580     }
00581     if (dev_fat[0].fat_levantada==FALSE) {
00582         levantar_fat();
00583     }
00584 
00585     
00586     int sector=(datos_archivo.sector*dev_fat[0].sectores_por_cluster)+dev_fat[0].root_dir_start+dev_fat[0].root_dir_size-2;
00587 
00588     sector = fat_next_sector(sector);
00589 
00590     while (  (sector > 0) && (sector < 0xff0) ) {
00591         kprintf("%d->", sector);
00592         sector = fat_next_sector(sector);
00593     }
00594     kprintf("FIN\n");    
00595 }       
00596 
00598 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 
00608 
00609 
00610 
00611 
00612 
00613 
00614 
00615 
00616 
00617 
00618 
00619 
00620 
00621 
00622