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