pid loader_load(pso_file* f, int pl) { //me guardo el cr3 viejo. uint_32 old_cr3 = rcr3(); //pido un directorio para la nueva tarea void* task_dir = mm_dir_new(); printf(" >loader_load: task_dir = %x", task_dir); //TODO VER CUANTA MEMORIA NECESITA REALMENTE void* puntero_page_tarea = mm_mem_alloc(); printf(" >loader_load: puntero page tarea : %x", (uint_32) puntero_page_tarea); //stacks de anillo 3 y 0 para la tarea void* task_stack3 = mm_mem_alloc(); void* task_stack0 = mm_mem_alloc(); printf(" >loader_load: pfi after allocs: kernel = %x | usr = %x", *kernel_pf_info, *usr_pf_info); //ver esto donde van mapeados los stacks mm_page_map(STACK_3_VIRTUAL, task_dir, (uint_32) task_stack3, 0, USR_STD_ATTR); mm_page_map(STACK_0_VIRTUAL, task_dir, (uint_32) task_stack0, 0, MM_ATTR_RW | MM_ATTR_US_S); //TODO ver estas direcciones temporales donde ponerlas mm_page_map(KERNEL_TEMP_PAGE,(mm_page *) old_cr3, (uint_32) task_stack0, 0, MM_ATTR_RW | MM_ATTR_US_S); //inicializamos la pila de nivel 0 para que tenga el contexto para //poder volver del switchto uint_32* stack0 = (uint_32*) (KERNEL_TEMP_PAGE + 0xffC); *stack0-- = 0x23; *stack0-- = STACK_3_VIRTUAL + 0x1000; *stack0-- = 0x202; *stack0-- = (pl)? 0x1B : 0x08; //Elijo el selector de segmento según el privilegio de la tarea *stack0-- = (uint_32) f->_main; *stack0-- = (uint_32) &task_ret; *stack0-- = resp(); *stack0-- = 0x0; *stack0-- = 0x0; *stack0-- = 0x0; mm_page_map((uint_32) f->mem_start, task_dir, (uint_32) puntero_page_tarea, 0, USR_STD_ATTR); //mapeo la direccion virtual temporal para copiar en la pagina que recien se me asigno. mm_page_map((uint_32) KERNEL_TEMP_PAGE,(mm_page *) old_cr3, (uint_32) puntero_page_tarea, 0, USR_STD_ATTR); tlbflush(); //copio la tarea desde donde esta a la pagina que acabo de mapear. uint_8* addr_to_copy = (uint_8*) KERNEL_TEMP_PAGE; uint_8* task_to_copy = (uint_8*) f; uint_32 cant_to_copy = f->mem_end_disk - f->mem_start; int i; printf(" >loader_load: task_to_copy = %x", task_to_copy); for (i = 0; i < cant_to_copy; i++) { *addr_to_copy++ = *task_to_copy++; } //tengo que armar la estreuctura uint_32 requested_pid = get_new_pid(); task_table[requested_pid].cr3 = (uint_32) task_dir; task_table[requested_pid].esp0 = STACK_0_VIRTUAL + 0xFD8; mm_page_free(KERNEL_TEMP_PAGE, (mm_page *) old_cr3); tlbflush(); sched_load(requested_pid); tasks_running++; printf(" >loader_load: finished loading to new pid %d", requested_pid); return requested_pid; }
void sched_unblock(pid pd) { sched_load(pd); }
uint_32 sys_fork(uint_32 org_eip, uint_32 org_esp) { //me guardo el cr3 viejo. uint_32 old_cr3 = rcr3(); printf(" >sys_fork: org_eip (%x), org_esp (%x)", org_eip, org_esp); //pido un directorio para la nueva tarea void* new_cr3 = mm_dir_fork((mm_page*) old_cr3); if (new_cr3 == NULL) { //No pudo hacerse fork de la estrucutra de paginación printf("! >sys_fork: no se pudo crear el directorio de la nueva tarea"); return -1; } printf(" >sys_fork: new_cr3 = %x", new_cr3); //stacks de anillo 3 y 0 para la tarea void* task_stack3 = mm_mem_alloc(); void* task_stack0 = mm_mem_alloc(); printf(" >sys_fork: paginas stack_ kernel %x | usr %x", task_stack0, task_stack3); //ver esto donde van mapeados los stacks mm_page_map(STACK_3_VIRTUAL, new_cr3, (uint_32) task_stack3, 0, USR_STD_ATTR); mm_page_map(STACK_0_VIRTUAL, new_cr3, (uint_32) task_stack0, 0, MM_ATTR_RW | MM_ATTR_US_S); //TODO ver estas direcciones temporales donde ponerlas mm_page_map(KERNEL_TEMP_PAGE,(mm_page *) old_cr3, (uint_32) task_stack0, 0, MM_ATTR_RW | MM_ATTR_US_S); //inicializamos la pila de nivel 0 para que tenga el contexto para //poder volver del switchto uint_32* stack0 = (uint_32*) (KERNEL_TEMP_PAGE + 0xffC); *stack0-- = 0x23; *stack0-- = org_esp; *stack0-- = 0x202; *stack0-- = 0x1B; *stack0-- = org_eip; *stack0-- = (uint_32) &fork_ret; *stack0-- = resp(); *stack0-- = 0x0; *stack0-- = 0x0; *stack0-- = 0x0; //Copio la pila de usuario como está //Innecesario, ya lo hace el fork mm_copy_vf((uint_32*)STACK_3_VIRTUAL, (uint_32)task_stack3, PAGE_SIZE); mm_page_free(KERNEL_TEMP_PAGE, (mm_page*) old_cr3); tlbflush(); //tengo que armar la estructura de proceso uint_32 requested_pid = get_new_pid(); task_table[requested_pid].cr3 = (uint_32) new_cr3; task_table[requested_pid].esp0 = STACK_0_VIRTUAL + 0xFD8; //Duplico los file descriptor actualizando referencias device_fork_descriptors(cur_pid, requested_pid); // esto esta mal.. tiene q decidir q numero devolver creo q necesitamos un semaforo! sched_load(requested_pid); tasks_running++; printf(" >sys_fork: forkeo finalizado en pid %d", requested_pid); mm_dump(); return requested_pid; }