// recibe una direccion y un perro, al cual debe mover en esa dirección // *** viene del syscall mover *** uint game_perro_mover(perro_t *perro, direccion dir) { int x, y; game_dir2xy(dir, &x, &y); int nuevo_x = perro->x + x; int nuevo_y = perro->y + y; //int viejo_x = perro->x; //int viejo_y = perro->y; uint cr3 = perro->cr3; // ~~~ completar ~~~ //verificar si se sale del tablero if (!game_es_posicion_valida(nuevo_x, nuevo_y)) { return NULL; } perro_t *otro_perro; //verificar si hay otro perro del mismo jugador ahi otro_perro = game_perro_hay_perro_de_jugador(perro->jugador, nuevo_x, nuevo_y); if ( otro_perro != NULL) { //game_perro_termino(otro_perro); return NULL; } jugador_t* otro_jugador; if (&jugadorA == perro->jugador) { otro_jugador = &jugadorB; } //verificar si hay otro perro del otro jugadr ahi otro_perro = game_perro_hay_perro_de_jugador(otro_jugador, nuevo_x, nuevo_y); if ( otro_perro != NULL) { //debemos matar al perro //sched_remover_tarea(sched_buscar_gdtindex_tarea_desde_perro(otro_perro)); game_perro_termino(otro_perro); } screen_borrar_perro(perro); //mapeamos como lo pide el enunciado la nueva posicion visitada en modo solo lectura mmu_mapear_pagina(mmu_xy2virtual(nuevo_x, nuevo_y), cr3, mmu_xy2fisica(nuevo_x, nuevo_y), 0x5); // luego copiamos código y pila a la nueva posición de memoria mmu_copiar_pagina(0x401000, mmu_xy2virtual(nuevo_x, nuevo_y)); // por último mapeamos la dirección 0x401000 a la nueva dirección fisica donde el codigo copiado // y la pila se alojan, con nivel de usuario, y de lectura/escritura mmu_mapear_pagina(0x401000, cr3, mmu_xy2fisica(nuevo_x, nuevo_y), 0x7); perro->x = nuevo_x; perro->y = nuevo_y; return 1; }
void mmu_inicializar() { int task_counter = 0; while(task_counter < 4){ mmu_inicializar_tarea_jugador(task_counter); task_counter++; } mmu_inicializar_tarea_arbitro(); pt_entry *pt = (pt_entry*) KERNEL_PAGE_TABLE; mmu_mapear_pagina(TASK_CODE, pt, TASK_IDLE_CODE_SRC_ADDR, 0x003); mmu_mapear_pagina(TASK_IDLE_STACK_RING_0, pt, TASK_IDLE_STACK_RING_0, 0x003); }
unsigned int mmu_inicializar_dir_tarea(taskType tipo, unsigned int fisica){ int *page_directory = mmu_proxima_pagina_fisica_libre(); // Limpiamos el directorio int i = 0; while (i < 1024) { page_directory[i] = 0; i++; } // Registramos la primer pagina en el directorio int *page_table = mmu_proxima_pagina_fisica_libre(); page_directory[0] = (int)page_table + ATTR_KERN; // En la tabla de paginas registramos las primeras 1024 con bloques // de 4kb int base_page_addr = 0; i = 0; while(i < 1024) { page_table[i] = base_page_addr + ATTR_KERN; base_page_addr += 4096; i++; } unsigned int cr3Tarea = (int) page_directory; mmu_mapear_pagina(fisica, rcr3(), fisica, ATTR_KERN); //tipo de tarea int* codigo_fuente = (int*) (IDLE_TASK + (inMemoryCodeOrder(tipo) * PAGE_SIZE)); mmu_copiar_pagina(codigo_fuente, (int*) fisica); mmu_unmapear_pagina(fisica, rcr3()); mmu_mapear_pagina(TASK_CODE, cr3Tarea, fisica, ATTR_USER); //En principio se mapea a si misma //No esta atacando a nadie mmu_mapear_pagina(TASK_CODE + PAGE_SIZE, cr3Tarea, fisica, ATTR_USER); return cr3Tarea; }
void mmu_remap_task_page(unsigned int taskNumber, unsigned int taskPageNumber, unsigned int newPhysicalAddress){ pagedir_entry* taskPageDir = mmu_get_task_pageDirAddress(taskNumber); switch(taskPageNumber){ case 1: mmu_mapear_pagina(TASK_VIRTUAL_P1/*0x40000000*/, taskPageDir, newPhysicalAddress, 1/*readWriteb*/, 1/*userSupervisorb, modo USUARIO*/); break; case 2: mmu_mapear_pagina(TASK_VIRTUAL_P2/*0x40001000*/, taskPageDir, newPhysicalAddress, 1/*readWriteb*/, 1/*userSupervisorb, modo USUARIO*/); break; case 3: //calculo direccion del dir. de tablas y tabla de paginas de la tarea mmu_mapear_pagina(TASK_VIRTUAL_P3/*0x40002000*/, taskPageDir, newPhysicalAddress, 0/*SOLO READ*/, 1/*userSupervisorb, modo USUARIO*/); break; } //notifico a context manager //actualizar informacion en base tareas(no me importa la idle) if(taskNumber<8){//ignoro la idle(task 8 contando desde 0) notificarCambioPagina(taskPageNumber/*numeroPaginaTarea*/, newPhysicalAddress, taskNumber); } }
void mmu_inicializar_tarea_jugador(unsigned int task_number){ unsigned int page_dir[] = {TASK_1_PAGE_DIR, TASK_2_PAGE_DIR, TASK_3_PAGE_DIR, TASK_4_PAGE_DIR}; unsigned int page_table[] = {TASK_1_PAGE_TABLE, TASK_2_PAGE_TABLE, TASK_3_PAGE_TABLE, TASK_4_PAGE_TABLE}; unsigned int code_dir[] = {TASK_1_CODE_PA, TASK_2_CODE_PA, TASK_3_CODE_PA, TASK_4_CODE_PA}; unsigned int stack_dir[] = {TASK_1_STACK_PA, TASK_2_STACK_PA, TASK_3_STACK_PA, TASK_4_STACK_PA}; unsigned int code_addr[] = {TASK_1_CODE_SRC_ADDR, TASK_2_CODE_SRC_ADDR, TAKS_3_CODE_SRC_ADDR, TASK_4_CODE_SRC_ADDR}; //Copio todo el bloque de código a mi proximo espacio. int i = 0; int *origen = (int*) code_addr[task_number]; int *destino = (int*) code_dir[task_number]; while(i < TAMANO_PAGINA){ destino[i] = origen[i]; i++; } pd_entry *pdentry = (pd_entry*) page_dir[task_number]; i = 0; //Inicializo en 0 la page directory. for(i = 0; i < 1024; i++){ pdentry[i] = (pd_entry) { (unsigned short) 0x000, (unsigned int) 0x00000 }; } //Mi primera entrada en la PDE para la tarea. pdentry[0] = (pd_entry) { (unsigned short) 0x007, (unsigned int) page_table[task_number] >> 12 // shifteo los 12 bits que me sobran a derecha }; //Creo la Page Table inicializada con todo en 0. pt_entry *pt = (pt_entry*) page_table[task_number]; i = 0; for(i = 0; i < 1024; i++){ pt[i] = (pt_entry){ (unsigned short) 0x000, (unsigned int) 0x00000 }; } i = 0; for(i = 0; i < 0x164; i++){ pt[i] = (pt_entry){ (unsigned short) 0x003, (unsigned int) i }; } mmu_mapear_pagina(TASK_CODE, pt, code_dir[task_number], 0x5); mmu_mapear_pagina(TASK_STACK, pt, stack_dir[task_number], 0x7); mmu_mapear_pagina(TABLERO_ADDR, pt, TABLERO_ADDR_PA, 0x5); } void mmu_inicializar_tarea_arbitro(){ //Copio todo el bloque de código a mi proximo espacio. int i = 0; int *origen = (int*) TASK_5_CODE_SRC_ADDR; int *destino = (int*) TASK_5_CODE_PA; while(i < TAMANO_PAGINA){ destino[i] = origen[i]; i++; } pd_entry *pdentry = (pd_entry*) TASK_5_PAGE_DIR ; i = 0; //Inicializo en 0 la page directory. for(i = 0; i < 1024; i++){ pdentry[i] = (pd_entry) { (unsigned short) 0x000, (unsigned int) 0x00000 }; } //Mi primera entrada en la PDE para la tarea. pdentry[0] = (pd_entry) { (unsigned short) 0x007, (unsigned int) TASK_5_PAGE_TABLE >> 12 // shifteo los 12 bits que me sobran a derecha }; //Creo la Page Table inicializada con todo en 0. pt_entry *pt = (pt_entry*) TASK_5_PAGE_TABLE; i = 0; for(i = 0; i < 1024; i++){ pt[i] = (pt_entry){ (unsigned short) 0x000, (unsigned int) 0x00000 }; } for(i = 0; i < 0x164; i++){ pt[i] = (pt_entry){ (unsigned short) 0x003, (unsigned int) i }; } mmu_mapear_pagina(TASK_CODE, pt, TASK_5_CODE_PA, 0x3); mmu_mapear_pagina(TASK_STACK, pt, TASK_5_STACK_PA, 0x3); mmu_mapear_pagina(TABLERO_ADDR, pt, TABLERO_ADDR_PA, 0x1); mmu_mapear_pagina(VIDEO, pt, VIDEO, 0x3); } void mmu_mapear_pagina(unsigned int dv, pt_entry* pt, unsigned int fisica, unsigned int attrs){ unsigned int posicion = (unsigned int) dv >> 12; pt[posicion] = (pt_entry){ (unsigned short) attrs, (unsigned int) fisica >> 12 }; }