Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;variables globales:
- ;actual=indice de a tarea actual
- ;reiniciada=indice de la tarea reiniciandose
- ;backup_eip= guarda las dirs de eip a restaurar
- ;reg_global=cada reg tiene su variable global
- tarea_offset: dd 0x00
- tarea_selector: dw 0x00
- ;
- ;pilas de tarea luego de ser interrumpida por el clk
- ;
- ; pila de nivel 0 pila de nivel 3
- ; -
- ; |---------------|<-- esp | |
- ; | eip | | |
- ; |---------------| | |
- ; | eflags | |--------->|---------------|
- ; |---------------| | | cosas |
- ; | esp3 |-------------------| | de la |
- ; |---------------| | tarea |
- ; | ss | | |
- ; |---------------| |---------------|
- ;+
- ;una tarea crashea, pasa a ejecutarse la interrupcion. La interrupcion setea la variable global interrumpida con el index de la tarea actual (la crasheada). Luego ejecuta limpiar_memoria. Despues llama a prox_indice y hace un jmp far a la siguiente tarea.
- ;La tarea siguiente, se encuentra finalizando la interrupcion de clk (el comportamiento normal del scheduler:ver apunte interrupcion de clk), (justo en la instruccion de abajo del jmp far del clk) cuando no hay una tarea siendo reiniciada, tiene el comportamiento usual de un scheduler, pero si estamos en la situacion de la interrupcion, llama a la función cambiar contexto. Cambiar_contexto hace los siguientes cambios en la pila
- ;cambiar_contexto
- ;
- ; pila nivel 0
- ; |---------------|<--esp
- ; | 0x3700000 | pila nivel 3 en 0x3700000 esta la funcion informar.
- ; |---------------| báicamente, reemplazamos el eip que estaba
- ; | eip | | | por el de la funcion informar, para que al salir
- ; |---------------| |----->|---------------| de la int de clk, al hacer iret, se popee en eip
- ; | eflags | | | reiniciada | ejecutando a continuación la función informar.
- ; |---------------| | |---------------| Ademas en la pila de nivel 3 agregamos en el tope
- ; | esp3 |------| | | el indice de la tarea siendo reiniciada que informar
- ; |---------------| | cosas | recibe como parametro.
- ; | ss | | de la |
- ; |-------------- | | tarea |
- ; | | |---------------|
- ;+
- ;
- ;Luego, la funcion informar llama a la syscall finaizar. Finalizar restaura el contexto de la tarea. Las pilas de la siguiente forma:
- ;restaurar_contexto
- ;
- ;
- ; pila nivel 0
- ; pila nivel 3
- ; |---------------|<--esp
- ; | eip_inf | | |
- ; |---------------| |---------------|
- ; | eflags | | reiniciada |
- ; |---------------| |----->|---------------|
- ; | esp3 |------| | |
- ; |---------------| | cosas |
- ; | ss | | de la |
- ; |-------------- | | tarea |
- ; | | |---------------|
- ;+ |
- ; |
- ; |
- ; v
- ;
- ; pila nivel 0
- ; pila nivel 3
- ; |---------------|<--esp
- ; | backup_eip | | |
- ; |---------------| |---------------|
- ; | eflags | | reiniciada |
- ; |---------------| |----->|---------------|
- ; | esp3 |------| | |
- ; |---------------| | cosas |
- ; | ss | | de la |
- ; |-------------- | | tarea |
- ; | | |---------------|
- ;esquema de interrupcion:
- ; tarea--->interrupcion--->prox tarea en informar--->_finalizar--->limpiar--->prox tarea
- ; ^ |
- ; ----------------
- ; 14 veces
- _isr32:
- mov [regs_global], regs ;para cada reg guardamos en una variable global que le corresponde
- call fin_intrpic
- call prox_indice
- mov [tarea_selector],ax
- jmp far [tarea_offset]
- cmp reiniciada,0
- je .fin
- ;nunca entra con la tarea reiniciada pues cae de regreso en la interrupcion
- call cambiar_contextos
- and dwors[esp+4], 0xfffffdff ;deshabilita las interrupciones seteando el bit 9 de eflags en 0
- .fin:
- mov regs [regs_global]
- iret;
- _int:
- pushad
- call interrupcion
- mov [tarea_selector],ax
- jmp far [tarea_offset]
- ;aca vuelve al dar la vuelta a las tareas
- mov [reiniciada],0
- or dword[esp+4], 0x00000200
- popad
- iret
- _finalizar:
- call int_finalizar
- or dword[esp+4], 0x00000200 ;restaurar eflags
- mov [tarea_selector],ax
- jmp far [tarea_offset]
- mov regs [regs_global]
- iret
- ;c:
- int int_finalizar(){
- restaurar_contexto();
- prox_indice();
- return actual;
- }
- int interrupcion(){
- reiniciada = actual;
- limpiar_memoria(actual);
- prox_indice();
- return actual;
- }
- void restaurar_contexto(){
- int* pila0 = (int*)tss->esp;
- pila0[0] = backup_eip;
- pila0[2] = pila0[2]+8; restaura esp pila3
- }
- void cambiar_contexto(){
- int* pila0 = (int*)tss->esp;
- int* pila3 = (int*)pila0[2];
- pila3 = pila3-8;
- pila3[0] = reiniciada;
- pila0[2]=pila3;
- modificar_eip_tss(actual, 0x3700000);
- }
- void modificar_eip_tss(int indice, int valor){
- int eip_ant = tss[indice_eip];
- backup_eip = eip_ant;
- tss[indice]->eip=valor;
- }
- void prox_indice(){
- actual=(actual++)%15 +1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement