/** * cargar_fat: Carga la tabla FAT en memoria (en una variable global) * * @return el estado de la operacion */ int cargar_fat() { int indice; int tamanio_fat; dword sector_fat; if ( sector_booteo == NULL ) { if ( cargar_BPB (sector_booteo) == ERROR ) { imprimir ("Error cargando el sector de booteo\n"); return ERROR; } } // obtengo el tamanio de la fat en bytes tamanio_fat = sector_booteo->BPB_tamanio_FAT * 512; // le aloco memoria fat = (byte*) sys_alocar ( tamanio_fat ); // inicializo la FAT con ceros setear_memoria ( fat, 0, tamanio_fat ); // obtengo el primer sector (LOGICO) donde comienza la tabla FAT // (el primer sector es el del BPB, luego del cual vienen los sectores // reservados, y a continuacion la tabla FAT). sector_fat = sector_booteo->BPB_cant_sectores_reservados + 1; // leo los N sectores que conforman la tabla FAT imprimir ( "Cargando FAT" ); for ( indice = 0; indice < sector_booteo->BPB_tamanio_FAT; indice++ ) { imprimir ( "." ); /* * sector_fat es un sector logico, el cual antes de leerlo hay que * trasnformarlo a CHS. * fat es el buffer donde leemos, pero hay que ir incrementandolo por * cada lectura(la primera vez (fat), la segunda (fat+512), y asi... */ if ( leer_sector_logico (sector_fat, fat + indice * 512) == LECTURA_ERRONEA ) { imprimir ( "Error al leer la tabla fat!\n" ); return ERROR; } // leo el siguiente sector logico sector_fat++; } imprimir ( "\n" ); #ifdef DEBUG // el MediaID es 0xF0 para disquettes! imprimir ( "FAT Cargada, MediaID: 0x%xb\n", *fat ); #endif return OK; }
/** * cargar_BPB: Carga el BIOS Parameter Block en memoria (en una variable global) * @param sector_booteo direccion en memoria de la variable conteniendo los * datos a leer * * @return el estado de la operacion */ int cargar_BPB (BPB* sector_booteo) { char* buffer; buffer = (char*) sys_alocar (512); if ( leer_sector ( 0, 0, 1, buffer ) == LECTURA_ERRONEA ) { return ERROR; } copiar_memoria ( buffer, sector_booteo, sizeof (BPB) ); return OK; }
/** * inicializa_teclado: Funcion utilizada para inicializar el teclado. * Se encarga de alocar el buffer_teclado, inicializar los indices del * buffer a 0. Deja habilitadas las teclas y los leds. * Tambien , el comando 0xF3 al port 0x60 setea la velocidad de retardo, * a continuacion se escribe al port 0x63 un byte con los valores: * * <PRE> * * +---+---+---+---+---+---+---+---+ * | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * +---+---+---+---+---+---+---+---+ * | | | | | | | | * | | | | | +---+---+--> Numero A * | | | | | * | | | +---+--> Numero B * | | | * | +---+--> Tiempo que transcurre desde que se presiona una tecla * | hasta que empieza a repetirse (en intervalos de 0.25seg). * | * +--> Siempre va seteado a cero * 1 * Tasa de Autorepeticion (Teclas/sec): --------------------------- * ( 8 + A ) * 2^B * 0.00417 * * Si seteamos al teclado para que espere 0.25 segundos y acepte 10 * caracteres por segundo, este byte deberia valer: * 0x2C = 0 01 01 100 -> A:4 B:1 * 0x40 = 0 10 00 000 * * </PRE> */ void inicializa_teclado() { //outb ( 0xFF, 0x60 ); // escribo el comando 0xFF RESET(incluye BAT) //while ( inb (0x60) != 0xAA ); // espero final OK del BAT. //while ( inb (0x60) != 0xFA ); // espero la senial de reconocimiento outb ( 0xF3, 0x60 ); // escribo el comando 0xF3 while ( inb (0x60) != 0xFA ); // espero la senial de reconocimiento outb ( 0x20, 0x60 ); // escribo los parametros del comando 0xF3 while ( inb (0x60) != 0xFA ); // vuelvo a esperar reconocimiento //Se inicializan los leds. Todos Apagados. setear_leds ( (byte)0, (byte)0, (byte)0 ); buffer_teclado = (char*) sys_alocar (LIMITE); buffer_teclado = setear_memoria (buffer_teclado, ASCII_FIN_LINEA, LIMITE); indice_lectura = 0; indice_escritura = 0; caracteres_leidos = 0; }
int sys_leer_entrada_dir ( char* entrada, dir* directorio ) { int i; static entrada_directorio* ed = NULL; //dir* directorio = direc + recuperar_base (); //char* entrada = ent + recuperar_base (); if ( directorio == NULL ) { return ERROR; } if ( ed == NULL ) { ed = (entrada_directorio*) sys_alocar ( directorio->cant_entradas ); } if ( directorio->indice == -1 ) { if ( leer_sector_logico (directorio->sector_a_leer++, ed) == LECTURA_ERRONEA ) { imprimir ( "Error leyendo directorio raiz!\n" ); return ERROR; } directorio->indice = 0; } if ( ed[directorio->indice].nombre[0] == ULTIMA_ENTRADA ) { return NULL; } for ( i = 0; i < 11; i++ ) { entrada[i] = ed[directorio->indice].nombre[i]; } entrada[i] = '\0'; if (directorio->indice+1 == directorio->cant_entradas) { directorio->indice = -1; } else { directorio->indice += 1; } return OK; }
int sys_ejecutar ( char* arch, char* args[] ) { int i, fd, idx_codigo, idx_dato; pcb* nueva_tarea; dword funcion; char* dato = (char*)alocar (11); char* archivo = arch + recuperar_base (); char** args1 = (char**) (((int)args) + recuperar_base() ); char* argu; if ( args1 != NULL ) { i = 0; imprimir ( "Mostrando argumentos:\n" ); while ( args1[i] != NULL ) { argu = (char*) ( ((int)args1[i]) + recuperar_base () ); imprimir ( "args[%d] = <%s>\n", i, argu ); i++; } for (i = 0; i < 12 && archivo [i] != '\0'; i++) { dato [i] = archivo [i]; } } else { imprimir ( "No se recibieron argumentos en ejecutar\n" ); } imprimir_cadena ( "Abriendo: <" ); imprimir_cadena ( archivo ); imprimir_cadena ( " - " ); imprimir_cadena ( dato ); imprimir_cadena ( ">\n" ); fd = abrir ( archivo ); funcion = (dword) sys_alocar ( tarea_actual->archivos [fd].ed.tamanio + TAMANIO_PILA_USUARIO ); if ( funcion == NULL ) { return -1; } if ( fd == ERROR ) { return -1; } else { idx_codigo = siguiente_indice_gdt (); setear_desc_seg ( SEG_CODIGO, funcion, &_gdt->descriptores[idx_codigo], 0xFFFFF ); // tarea_actual->archivos [fd].ed.tamanio ); idx_dato = siguiente_indice_gdt (); setear_desc_seg ( SEG_DATOS, funcion, &_gdt->descriptores[idx_dato], 0xFFFFF ); // tarea_actual->archivos [fd].ed.tamanio + // TAMANIO_PILA_USUARIO ); leer_archivo (fd, (void*)funcion, tarea_actual->archivos [fd].ed.tamanio); nueva_tarea = crear_tarea ((handler_tarea)funcion); //nueva_tarea->dato = archivo; //nueva_tarea->dato = arch; nueva_tarea->dato = dato; nueva_tarea->tarea->eip = 0x00; nueva_tarea->tarea->cs = 8 * idx_codigo; nueva_tarea->tarea->ds = 8 * idx_dato; nueva_tarea->tarea->es = nueva_tarea->tarea->ds; nueva_tarea->tarea->fs = nueva_tarea->tarea->ds; nueva_tarea->tarea->gs = nueva_tarea->tarea->ds; nueva_tarea->selector_ds = nueva_tarea->tarea->ds >> 3; /* nueva_tarea->tarea->esp = funcion + TAMANIO_PILA_USUARIO + tarea_actual->archivos [fd].ed.tamanio; nueva_tarea->tarea->ss = nueva_tarea->tarea->ds; nueva_tarea->tarea->ss0 = nueva_tarea->tarea->ds; nueva_tarea->tarea->ss1 = nueva_tarea->tarea->ds; nueva_tarea->tarea->ss2 = nueva_tarea->tarea->ds; */ /* imprimir_cadena ("poniendo en ejecucion a "); imprimir_cadena (dato); imprimir_cadena ("\n"); */ agregar (nueva_tarea); //cerrar ( fd ); } return nueva_tarea->pid; }
/** * leer_archivo: lee desde un file descriptor, que representa un archivo, * analoga a la funcion read de UNIX * @param fd descriptor de archivo * @param buffer posicion de memoria donde se leera * @param cant cantidad de bytes a leer * @return estado de la lectura */ int leer_archivo ( int fd, void* buffer, unsigned int cant ) { unsigned int cluster_a_leer; unsigned int tam_lectura; char* buffer_temporal; int sector_logico; int bytes_leidos = 0; int indice_copia = 0; int idx; descriptor_archivo descr = tarea_actual->archivos [ fd ]; #ifdef DEBUG imprimir ( "Se va a leer: <" ); for ( idx = 0; idx < 11; idx++ ) { imprimir ( "%c", descr.ed.nombre[idx] ); } imprimir ( ">\n" ); #endif buffer_temporal = (char*) sys_alocar ( 512 ); indice_copia = descr.posicion_actual % 512; while ( cant > 0 ) { // si todavia tengo que leer el sector actual (aun no avanzo). if ( descr.posicion_actual == 0 || (descr.posicion_actual % 512) != 0 ) { cluster_a_leer = descr.cluster_actual; if ( cant < ( 512 - (descr.posicion_actual % 512) ) ) { tam_lectura = cant; } else { tam_lectura = 512 - ( descr.posicion_actual % 512 ); } } else { cluster_a_leer = proximo ( descr.cluster_actual ); descr.cluster_actual = cluster_a_leer; if ( cluster_a_leer == 0x0 || (cluster_a_leer & 0x0FF0) == 0x0FF0 ) { imprimir ( "ultimo cluster: 0x%x\n", cluster_a_leer ); //return bytes_leidos; break; } tam_lectura = cant > 512 ? 512 : cant; } if ( tam_lectura + bytes_leidos > descr.ed.tamanio ) { tam_lectura = descr.ed.tamanio - bytes_leidos; tam_lectura = tam_lectura > 512 ? 512 : tam_lectura; cant = 0; imprimir ("se quiere leer mas de lo que se puede!\n" ); } sector_logico = cluster_a_lba ( cluster_a_leer ); leer_sector_logico ( sector_logico, buffer_temporal ); for ( idx = indice_copia; idx < (indice_copia+tam_lectura); idx++ ) { ((char*)buffer) [ idx - indice_copia + bytes_leidos ] = buffer_temporal [ idx ]; } cant -= tam_lectura; descr.posicion_actual += tam_lectura; bytes_leidos += tam_lectura; indice_copia += tam_lectura; indice_copia = indice_copia == 512 ? 0 : indice_copia; } tarea_actual->archivos [ fd ] = descr; return bytes_leidos; }