Beispiel #1
0
//Salva contexto de la tarea anterior,carga contexto idle y actualiza las estructuras
unsigned short saltar_idle(){
	
	
	tss* tss_gdt_a_liberar;
	unsigned short res = proximo_indice_gdt();
	if (res == 0x80){
		tss_gdt_a_liberar = &tss2;
	} else {
		tss_gdt_a_liberar = &tss1;
	}

	tss* tss_a_salvar = (tarea_anterior == IDLE) ? &tss_idle : &tareas_tss[tarea_anterior];
		
	// Salvo el contexto de la tarea anterior
	tss_copy(tss_gdt_a_liberar, tss_a_salvar);
	
	// Cargo el conexto de la idle.
	tss_copy(&tss_idle,tss_gdt_a_liberar);

	
	tarea_anterior	=	tarea_actual;
	tarea_actual	=	IDLE;
	
	if (indice_gdt == 1){
		indice_gdt = 2;
		 
	}else {
		indice_gdt	=	1;
	}
	
	return res;
}
Beispiel #2
0
void tss_inicializar_tarea_idle () {
  tss_idle.ptl      = 0x0;
  tss_idle.unused0  = 0x0;
  tss_idle.esp0     = 0x27000;
  tss_idle.ss0      = 0b1011000;
  tss_idle.unused1  = 0x0;
  tss_idle.esp1     = 0x0;
  tss_idle.ss1      = 0x0;
  tss_idle.unused2  = 0x0;
  tss_idle.esp2     = 0x0;
  tss_idle.ss2      = 0x0;
  tss_idle.unused3  = 0x0;
  tss_idle.cr3      = 0x27000;
  tss_idle.eip      = 0x20000;
  tss_idle.eflags   = 0x00000202;  /* INTERRUPCIONES. CHEQUEAR MANUAL. */
  tss_idle.eax      = 0x0;
  tss_idle.ecx      = 0x0;
  tss_idle.edx      = 0x0;
  tss_idle.ebx      = 0x0;
  tss_idle.esp      = 0x27000;
  tss_idle.ebp      = 0x27000;
  tss_idle.esi      = 0x0;
  tss_idle.edi      = 0x0;
  tss_idle.es       = 0b1011000;
  tss_idle.unused4  = 0x0;
  tss_idle.cs       = 0b1001000;  /* IDLE VIVE EN KERNEL */
  tss_idle.unused5  = 0x0;
  tss_idle.ss       = 0b1011000;
  tss_idle.unused6  = 0x0;
  tss_idle.ds       = 0b1011000;
  tss_idle.unused7  = 0x0;
  tss_idle.fs       = 0b1011000;
  tss_idle.unused8  = 0x0;
  tss_idle.gs       = 0b1011000;
  tss_idle.unused9  = 0x0;
  tss_idle.ldt      = 0x0;
  tss_idle.unused10 = 0x0;
  tss_idle.dtrap    = 0x0;  /* ??? */
  tss_idle.iomap    = 0xffff;
  
  tss_copy(&tss_next_1, &tss_idle);
  tss_copy(&tss_inicial, &tss_idle);
}
Beispiel #3
0
unsigned short sched_montar_idle () {
  unsigned short r;
  tss *anterior;
  
  anterior = guardar_tanquecito ? &tss_tanques[_tarea_actual] : &tss_idle;
  
  /* Se entiende leyendo sched_proxima_tarea. */
  if (GDT_TSS_1_BUSY()) {
    tss_copy(anterior, tss_tarea_2);
    tss_copy(tss_tarea_2, &tss_idle);
  } else {
    tss_copy(anterior, tss_tarea_1);
    tss_copy(tss_tarea_1, &tss_idle);
  }
  
  r = GDT_TSS_1_BUSY() ? GDT_TSS_2 << 3 : GDT_TSS_1 << 3;
  guardar_tanquecito = 1 - _esta_corriendo_la_idle;
  _esta_corriendo_la_idle = TRUE;
  
  return r;
}
Beispiel #4
0
// Prepara el salto para una tarea de usuario.
unsigned short sched_cambio_task(){
	
	tss* tss_gdt_a_liberar;
	
	unsigned short prox_tarea = sched_proximo_indice();

	// Si solo hay 1 tarea, no salto.
	if (tarea_actual == prox_tarea) return 0;

	unsigned short res = proximo_indice_gdt();
	if (res == 0x80){
		tss_gdt_a_liberar = &tss2;
	} else {
		tss_gdt_a_liberar = &tss1;
	}
	
	// Cuando recien empiezo con las tareas, tarea_anterior vale 88.
	// Con lo cual, no tengo que salvar el contexto de "tarea_anterior".
    if (tarea_anterior == IDLE){
		// Salvo contexto de la idle.
		tss_copy(tss_gdt_a_liberar,&tss_idle);
	} else if (tarea_anterior != 88 ){
		// Salvo contexto de la tarea anterior.
		tss_copy(tss_gdt_a_liberar, &tareas_tss[tarea_anterior]);
	}
	// Cargo el contexto de la tarea a ejecutar.
	tss_copy(&tareas_tss[prox_tarea],tss_gdt_a_liberar);
	
	tarea_anterior	=	tarea_actual;
	tarea_actual	=	prox_tarea;
	
	if (indice_gdt == 1 ){
		indice_gdt	=	2;
	} else {
		indice_gdt	=	1;
	}
	return res;

}
Beispiel #5
0
void sched_inicializar () {
  unsigned int i;
  
  for (i = 0; i < CANT_TANQUES; i++) {
    tareas_vivas[i] = TRUE;
  }
  
  tss_tarea_1 = &tss_next_1;    /* Tienen que apuntar a algo asi no */
  tss_tarea_2 = &tss_next_2;    /* frutean al ser sobreescritas.    */
  
  tss_copy(tss_tarea_1, &tss_idle);
  _esta_corriendo_la_idle = TRUE;
  guardar_tanquecito = TRUE;
  _estan_todas_muertas = TRUE;
  
  _tarea_actual = CANT_TANQUES - 1;
  
  primera_vez = TRUE;
}
Beispiel #6
0
unsigned short sched_proxima_tarea () {
  
  unsigned short r;
  static tss *proximo, *anterior;
  
  /**
   * Si hay que guardar el contexto de un tanque, lo hacemos.
   * Si no, hay que guardar el contexto de la idle.
   **/
  anterior = guardar_tanquecito ? &(tss_tanques[_tarea_actual]) : &tss_idle;
  
  proximo = proxima_tarea();
  /**
   * Si proximo devolvio NULL, o estan todas muertas,
   * no hay que saltar a otra tarea.
   **/
  if (proximo == NULL || _estan_todas_muertas) {
    return 0;
  }
  
  if (GDT_TSS_1_BUSY()) {
    if (primera_vez) {
      /**
       * Como es la primera vez, no hace falta guardar el contexto
       * de la tarea anterior.
       **/
      tss_copy(tss_tarea_2, &tss_tanques[0]);
      primera_vez = FALSE;
    } else {
      /**
       * Se copia en anterior (que apunta a la estructura correcta)
       * el contexto viejo, y se sobreescribe ese contexto en la gdt
       * con el contexto de la proxima tarea a ejecutar.
       **/
      tss_copy(anterior, tss_tarea_2);
      tss_copy(tss_tarea_2, proximo);
    }
  } else {
    /* Comentarios idem. */
    if (primera_vez) {
      tss_copy(tss_tarea_1, &tss_tanques[0]);
      primera_vez = FALSE;
    } else {
      tss_copy(anterior, tss_tarea_1);
      tss_copy(tss_tarea_1, proximo);
    }
  }
  
  /**
   * Si la entrada del selector de la tss 1 en la gdt esta ocupada,
   * devuelvo el selector de segmento de la entrada del selector de
   * la tss 2. Si no, devuelvo el de la tss 1.
   **/
  r = GDT_TSS_1_BUSY() ? GDT_TSS_2 << 3 : GDT_TSS_1 << 3;
  
  /**
   * guardar_tanquecito va a valer 1 si no se esta corriendo la idle,
   * 0 en caso contrario.
   * Supongamos que viene corriendo la tarea 1 en la tss 1 y hace un syscall.
   * Se monta la idle [-> _esta_corriendo_la_idle = 1, y su contexto esta en
   * la tss 2]. Llega la interrupcion del clock, y hay que hacer context
   * switch. Se hace toda la saraza de arriba, y se llega a este cacho de
   * codigo. El codigo de la tarea 2 esta montado en la tss 1. En el proximo
   * clock, voy a tener que guardar el contexto de la idle. Como todavia
   * _esta_corriendo_la_idle vale 1, guardar_tanquecito va a pasar a valer 0,
   * y en el proximo clock, efectivamente anterior va a apuntar a la tss de
   * la tarea idle.
   **/
  guardar_tanquecito = 1 - _esta_corriendo_la_idle;
  
  /* Como cambie de tarea, _NO_ esta corriendo la idle. */
  _esta_corriendo_la_idle = FALSE;
  
  return r;
  
}