La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Lic.Graciela De Luca UNLAM. Lic.Graciela De Luca 2 Niveles en los Sistemas Operativos USUARIOS PROGRAMAS DEL SISTEMA INTERPRETE DE COMANDOS UTILIDADES.

Presentaciones similares


Presentación del tema: "Lic.Graciela De Luca UNLAM. Lic.Graciela De Luca 2 Niveles en los Sistemas Operativos USUARIOS PROGRAMAS DEL SISTEMA INTERPRETE DE COMANDOS UTILIDADES."— Transcripción de la presentación:

1 Lic.Graciela De Luca UNLAM

2 Lic.Graciela De Luca 2 Niveles en los Sistemas Operativos USUARIOS PROGRAMAS DEL SISTEMA INTERPRETE DE COMANDOS UTILIDADES PARA PROCESOS UTILIDADES PARA ARCHIVOS LLAMADAS AL SISTEMA SISTEMA OPERATIVO

3 Lic.Graciela De Luca 3 Systems Calls: Interfaz que ofrece el Sistema Operativo al resto de los programas que les permite solicitarle algún trabajo Son servicios para: Interactuar con el Hardware Gestión de procesos Manejo de memoria Señales Tiempo Etc. Los servicios se ofrecen por medio de Llamadas al Sistema (Sistem calls) Las invoca un proceso de usuario y son servidas por el kernel

4 Lic.Graciela De Luca 4 Interfaces de los Sistemas Operativos Posix1 Posix es el nombre común del estandar IEEE1003.1:1996 Nos encontramos con la versión estándar de 1990 (sin hilos ): Llamadas al sistema Funciones de C estandarizadas (Ansi C) Surgió para estandarizar los sistemas Unix Permite código fuente portable Muchos sistemas cumplen con ella: UNIX, Linux, Windows NT,VMS y Os2 Win32 Interfaz común a todos los sistemas de Microsoft Windows Ningún otro sistema cumple con ella

5 Lic.Graciela De Luca 5 Ventajas de la capa intermedia de llamadas al sistema Facilita la programación. No es necesario conocer a fondo el HW Incrementa la seguridad del sistema, ya que el kernel puede comprobar que los parámetros de la llamada al sistema son correctos antes de intentar servirla Hace los programas más portables ya que usan interfaces comunes

6 Lic.Graciela De Luca 6 Llamadas al sistema y APIs Es necesario resaltar la diferencia entre un API y el conjunto de llamadas al sistema API: Application Programming Interface, interfaz de programación de aplicaciones. Dos niveles diferenciados Llamadas al sistema API Interfaz ofrecida para el programador por una biblioteca de funciones Interfaz ofrecida por el kernel

7 Lic.Graciela De Luca 7 Interfaz con el sistema operativo Se pueden distinguir dos puntos de vista en la interfaz ofrecida por las llamadas al sistema: La interfaz ofrecida por el núcleo del sistema operativo. Es una interfaz definida a nivel de lenguaje ensamblador. Depende directamente del "hardware" sobre el cual se está ejecutando el S.O La interfaz ofrecida al programador o usuario (API). MSDOS Documentada a nivel de ensamblador: Interrupción a la que hay que llamar, valores de los registros que hay que cargar y valores de retorno. UNIX Funciones estándar en lenguaje C. P.ej. int kill (pid_t pid, int sig);

8 Lic.Graciela De Luca 8 Interfaz ofrecida por el núcleo El núcleo de Linux, en IA32, utiliza la instrucción int 0x80 como puerta de entrada en el núcleo. (win 32 usa Int 0x2E) El handler de la interrupción software se instala en la función trap_init() [ arch/i386/kernel/traps.c] arch/i386/kernel/traps.c El número de la interrupción software esta definido por la constante SYSCALL_VECTOR [include/asm-i386/hw_irq.h#L19 ]/hw_irq.h#L void __init trap_init (void) 917 { set_trap_gate(0,÷_error); 924 set_trap_gate(1,&debug); 925 set_intr_gate(2,&nmi); 926 set_system_gate(3,&int3); /* int3-5 can be called from all */ 927 set_system_gate(4,&overflow); set_system_gate(SYSCALL_VECTOR,&system_call); }

9 Lic.Graciela De Luca 9 Interfaz ofrecida por el núcleo PARÁMETROS DE ENTRADA Linux los pasa en los siguientes registros del procesador. %ebx arg 1 %ecx arg 2 %edx arg 3 %esi arg 4 %edi arg 5 Código del servicio requerido en el registro %eax. En el archivo include/asm-i386/unistd.h aparecen listadas todas las llamadas al sistema que ofrece Linux con su correspondiente número.include/asm-i386/unistd.h Linux VALORES DE SALIDA En el registro %eax se devuelve el código de retorno.

10 Lic.Graciela De Luca 10 Todas las implementaciones de UNIX disponen de unas bibliotecas de usuario que esconden la implementación concreta de las llamadas al sistema (la interfaz real ofrecida por el S.O.) y ofrecen al programador una interfaz C que presenta las siguientes ventajas: Facilidad de uso al acceder desde un lenguaje de alto nivel. Portabilidad entre arquitecturas: Linux-sparc, Linux-i386, etc. Portabilidad entre diferentes versiones de UNIX: estándar POSIX. El estándar POSIX se define sólo a nivel de interfaz, no a nivel de implementación real. Documentación de llamadas al sistema: sección 2 del manual de UNIX ej.# man 2 kill Interfaz ofrecida al programador (API)

11 Lic.Graciela De Luca 11 Llamadas al sistema y APIs EJ: La función fork() del Lenguaje C no realiza el servicio fork, solo lo solicita al sistema operativo. Las funciones que solicitan servicios se componen de : 1. Una parte inicial que prepara los parámetros del servicio, tal como los espera el SO 2. La instrucción INT 0x80 que realiza el paso al SO 3. Una parte final que recoge los parámetros de contestación del SO para devolverlos al programa que hizo la llamada

12 Lic.Graciela De Luca 12 Proceso de llamada

13 Lic.Graciela De Luca 13 Proceso de llamada El proceso de usuario realiza una llamada a la función del API correspondiente (wrapper routine) La función del API prepara los parámetros de entrada y realiza una interrupción software, generando con ello la llamada al sistema. Esto eleva una excepción (0x80) Se cambia a modo kernel y se ejecuta el manejador de excepción, en este caso de llamada al sistema (system call handler) El manejador determina la llamada al sistema y llama a la función de servicio de la llamada al sistema (system call service routine)

14 Lic.Graciela De Luca 14 Llamadas al sistema y APIs En general, las llamadas al sistema estarán encapsuladas en funciones del API de programación del sistema operativo Las funciones del API encapsulan llamadas al sistema rutinas envoltorio (wrapper routines) No necesariamente todas las funciones del API encapsulan llamadas al sistema. También, una función del API puede realizar varias llamadas al sistema o varias funciones realizar la misma llamada con diferentes parámetros y funcionalidad añadida. Estándar POSIX: interfase entre la API de programación y S.CALL, no es la implementación de la S.CALL Las llamadas al sistema, pertenecen al kernel. Las funciones de biblioteca (API) son software a nivel usuario.

15 Lic.Graciela De Luca 15 Biblioteca de llamadas al sistema libc contiene todas las llamadas al sistema Oculta los detalles de la interfaz de las llamadas al sistema del núcleo en forma de funciones en C. Las funciones trasladan los parámetros que reciben, normalmente a traves de la pila, en los registros del procesador apropiados, invocan al S.O., recogen el código de retorno (en la variable errno), etc. Existen casos en los que dos llamadas al sistema de la biblioteca coinciden con la misma llamada al sistema "real" (P.Ej. waitpid y wait4 invocan ambas a la llamada al sistema wait4).

16 Lic.Graciela De Luca 16 Biblioteca de llamadas al sistema Algunas supuestas llamadas al sistema ofrecidas por la biblioteca son implementadas completamente por ella misma (el núcleo del S.O. no se invoca) Inicialmente, en Linux, la libc la mantenían Linus Torvalds et al.. Actualmente, se utiliza la biblioteca de GNU (glibc). libc.a biblioteca estática libc.so biblioteca dinámica El código de la biblioteca NO pertenece al núcleo del S.O., sino que está en el espacio de direcciones del usuario.

17 Lic.Graciela De Luca 17 Código de retorno En la IA32, Linux devuelve el valor de retorno de la S.Call en el registro %eax. Si no ha tenido éxito, el valor devuelto es negativo. Si es negativo, la biblioteca copia dicho valor sobre una variable global llamada errno y devuelve -1. Algunas llamadas realizadas con éxito pueden devolver un valor negativo (p.ej. lseek).

18 Lic.Graciela De Luca 18 Código de retorno El rango de errores se encuentra entre -1 y (0xfffff001). La biblioteca debe ser capaz de determinar cuándo el valor devuelto es un error y tratarlo de forma adecuada. La rutina syscall_error es la encargada de hacerlo. La variable errno contiene el código de error de la última llamada que falló. Una llamada relizada con éxito no modifica errno. (# man 3 errno) La variable errno está declarada en la propia biblioteca.

19 Lic.Graciela De Luca 19 Entrando en el núcleo La int 0x80 produce un salto a la. función system_call (zona de código del S.O entry.S L187) entry.S L187 La interrupción 0x80 se asocia con la función system_call al inicializar Linux en la línea 943 de traps.c de la función trap_init() invocada desde la función start_kernel de main.c L545traps.cmain.c L545

20 Lic.Graciela De Luca 20 En el proceso de salto... El procesador pasa de modo usuario ("ring level" 3 en la IA32) a modo supervisor ("ring level" 0). Se cambia el puntero de pila para que apunte a la pila del núcleo y se guardan en dicha pila algunos registros (SS, ESP, EFLAGS, CS, EIP). En IA32 cada nivel de privilegio tiene un puntero de pila distinto por motivos de seguridad.

21 Lic.Graciela De Luca 21

22 Lic.Graciela De Luca 22 Dentro de system_call (entry.S )system_call 194 ENTRY(system_call) 195 pushl %eax # save orig_eax 196 SAVE_ALL 197 GET_CURRENT(%ebx) # save punt al PCB 198 testb $0x02,tsk_ptrace(%ebx) # PT_TRACESYSPT_TRACESYS 199 jne tracesys 200 cmpl $(NR_syscalls),%eax 201 jae badsys # retorna con el cod error ENOSYS 202 call *SYMBOL_NAME(sys_call_table)(,%eax,4) 203 movl %eax,EAX(%esp) # save valor de retorno 204 ENTRY(ret_from_sys_call) 205 cli # need_resched y testea señales atomic 206 cmpl $0,need_resched(%ebx) 207 jne reschedule 208 cmpl $0,sigpending(%ebx) 209 jne signal_return 210 restore_all: 211 RESTORE_ALL

23 Lic.Graciela De Luca 23 1º guarda el código de la llamada al sistema en la pila del núcleo (entry.S#L195]).entry.S#L195 2º A continuación es importante guardar todos los registros del procesador con la macro SAVE_ALL]) (entry.S#L85)entry.S#L85 3º Se pone el puntero al PCB de la tarea actual en el registro %ebx (#197 ).#197

24 Lic.Graciela De Luca 24 4º Se verifica si el proceso padre está monitorizando este proceso (#198 ), en cuyo caso se ejecuta el código tracesys.(#198 ) Para verificar algunas condiciones sobre el estado del proceso actual se accede a su PCB a través de su registro %ebx. Para acceder a los campos de la estructura struct task_struct (sched.h#L281) se utilizan desplazamientos fijos definidos al principio del archivo entry.S. [70-80]sched.h#L281[70-80] Se puede ver la correspondencia en la propia estructura sched.hsched.h

25 Lic.Graciela De Luca 25 El código de tracesys informa al proceso padre de que su hijo está realizando una llamada al sistema, antes y después de servirla.tracesys 5ºSe comprueba que el número de llamada pedido es válido (si está dentro del rango). Si no es válido, se ejecuta el código de badsys [entry.S#L243] que retorna inmediatamente con el código de error ENOSYS. (entry.S [ ])entry.S#L243entry.S [ ])

26 Lic.Graciela De Luca 26 6º Se llama a la función que sirve la llamada pedida: 202 call *SYMBOL_NAME(sys_call_table)(,%eax,4) sys_call_table [entry.S#L397] es un vector de direcciones de salto que contiene las direcciones de la funciones que sirven cada una de las llamadas al sistema. Se utiliza el registro %eax como índice, teniendo en cuenta que cada dirección ocupa 4 bytes.entry.S#L397 7º Finalmente se pone en el registro %eax el código de retorno, y se ejecuta el código de ret_from_sys_call [entry.S#L204].entry.S#L204 Realmente se almacena el valor del registro %eax en la posición que ocupa dicho registro en la pila del núcleo EAX(%esp) (entry.S#L55).entry.S#L55 Al comienzo del archivo entry.S se han definido constantes que permiten acceder a los registros almacenados en la pila utilizando el puntero %esp (entry.S [49-63])entry.S [49-63])

27 Lic.Graciela De Luca 27 Cuando se saquen todos los registros de la pila con la macro RESTORE_ALL (entry.S#L100), el registro %eax se establecerá al valor de retorno (que es lo que espera la biblioteca libc). entry.S [ ]entry.S#L #define RESTORE_ALL \ 101 popl %ebx; \ 102 popl %ecx; \ 103 popl %edx; \ 104 popl %esi; \ 105 popl %edi; \ 106 popl %ebp; \ 107 popl %eax; \ 108 1: popl %ds; \ 109 2: popl %es; \ 110 addl $4,%esp; \ 111 3: iret;

28 Lic.Graciela De Luca 28 Recolección de parámetros En C normalmente se utiliza la pila para pasar parámetros entre funciones. Antes de realizar la llamada a una función se insertan en la pila todos los parámetros luego se invoca a la función y ésta lee los parámetros de la pila.

29 Lic.Graciela De Luca 29

30 Lic.Graciela De Luca 30 En nuestro caso, la macro SAVE_ALL (entry.S#L85) guarda los registros (que es donde se reciben los parámetros de las llamadas) en la pila (push)entry.S#L85 Si llamamos a una función C, ésta se comportará como si otra función en C le hubiera pasado los parámetros.

31 Lic.Graciela De Luca 31 Ejecución de la llamada al sistema Ej: llamada kill, cuando se ejecute la instrucción 202 call *SYMBOL_NAME(sys_call_table)(,%eax,4) llama a la función C que se encuentra en la entrada 37 (include/asm- i386/unistd.h#L44) de la tabla sys_call_table [entry.S#L436].include/asm- i386/unistd.h#L44sys_call_table El código de la biblioteca libc se asigno el valor 0x25(37) al registro %eax antes de ejecutar la instrucción int 0x80:... a: b mov $0x25,%eax f: cd 80 int $0x80... El tamaño de cada dirección es de 32 bits, o sea 4 bytes. La función invocada es sys_kill(int pid, int sig) [kernel/signal.c#L978], que se encargará de enviar la señal sig al proceso con pid pid.kernel/signal.c#L978

32 Lic.Graciela De Luca 32 sys_kill(int pid, int sig) 978 sys_kill(int pid, int sig) 979 { 980 struct siginfo info; info.si_signo = sig; 983 info.si_errno = 0; 984 info.si_code = SI_USER; 985 info.si_pid = current->pid; 986 info.si_uid = current->uid; return kill_something_info(sig, &info, pid); 989 } 990

33 Lic.Graciela De Luca 33 Ejecución de la llamada al sistema Los parámetros que el usuario le paso a la función kill de la biblioteca libc han pasado por los registros %ebx y %ecx, Se han copiado en la pila del núcleo y ese valor de la pila, en el lenguaje C, se ve ahora como los parámetro pid y sig de la función sys_kill.

34 Lic.Graciela De Luca 34 Saliendo del núcleo: ret_from_syscall Al finalizar la ejecución de la llamada al sistema se ejecuta el código que se encuentra en ret_from_sys_call [entry.S#L204].entry.S#L204 Este código lleva a cabo algunas comprobaciones antes de volver a modo usuario.

35 Lic.Graciela De Luca 35 Se deshabilitan las interrupciones. Durante la ejecución de la llamada al sistema el proceso ha podido cambiar de estado, y por lo tanto, haberse marcado la necesidad de planificar de nuevo, poniendo su campo need_resched a.T. Aquí se comprueba si esta variable es.T. y en caso afirmativo saltamos a reschedule, donde se llama al planificador [sched.c#L539] (#L206 [entry.S#L206]). (entry.S [ ])sched.c#L539[entry.S#L206]entry.S [ ]) 258 reschedule: 259 call SYMBOL_NAME(schedule) # test 260 jmp ret_from_sys_call

36 Lic.Graciela De Luca 36 Saliendo del núcleo: ret_from_syscall Se comprueba si el proceso activo tiene señales pendientes, en cuyo caso se le envían en el código de signal_return [entry.S#L208 ]entry.S#L208

37 Lic.Graciela De Luca ALIGN 214 signal_return: 215 sti 216 testl $(VM_MASK),EFLAGS(%esp) 217 movl %esp,%eax 218 jne v86_signal_return 219 xorl %edx,%edx 220 call SYMBOL_NAME(do_signal) 221 jmp restore_all 222

38 Lic.Graciela De Luca 38 Finalmente se restauran todos los registros con RESTORE_ALL entry.S#L100 (incluido %eax )entry.S#L100 Se retorna de la interrupción (int), reponiendo el modo del procesador y la pila a la que tiene acceso el proceso en modo usuario. Se puede observar que la ejecución más frecuente de system_call [entry.S#L187] (la llamada es correcta, no está siendo monitorizada, no hay que replanificar y no hay señales pendientes) está optimizada para no tomar absolutamente ningún salto, a excepción de la propia llamada a la función.entry.S#L187

39 Lic.Graciela De Luca 39 Resumen 1. La biblioteca coloca en los registros del procesador los parámetros de la llamada. 2. Se produce la interrupción software (trap) 0x80. El descriptor de interrupción. 0x80 apunta a la rutina system_call. 3. Se guardan el registro %eax. El resto de los registros con SAVE_ALL. 4. Se verifica que el número de llamada al sistema corresponde con una llamada válida. 5. Se salta a la función que implementa el servicio pedido: call *SYMBOL_NAME(sys_call_table)(,%eax,4)

40 Lic.Graciela De Luca 40 Resumen Si mientras se atendía la llamada al sistema se ha producido algún evento que requiera llamar al planificador, se llama en este punto. Si el proceso al que se va a retornar tiene señales pendientes, se le envían ahora. Se restauran los valores de los registros con RESTORE_ALL y se vuelve de la interrupción software. La biblioteca comprueba si la llamada ha producido algún error, y en este caso guarda en la variable errno el valor de retorno.

41 Lic.Graciela De Luca 41

42 Lic.Graciela De Luca #define SAVE_ALL \ 86 cld; \ 87 pushl %es; \ 88 pushl %ds; \ 89 pushl %eax; \ 90 pushl %ebp; \ 91 pushl %edi; \ 92 pushl %esi; \ 93 pushl %edx; \ 94 pushl %ecx; \ 95 pushl %ebx; \ 96 movl $(__KERNEL_DS),%edx; \ 97 movl %edx,%ds; \ 98 movl %edx,%es; volvervolver

43 Lic.Graciela De Luca /* 71 * these are offsets into the task-struct. 72 */ 73 state = 0 74 flags = 4 75 sigpending = 8 76 addr_limit = exec_domain = need_resched = tsk_ptrace = processor = 52 VOLVER


Descargar ppt "Lic.Graciela De Luca UNLAM. Lic.Graciela De Luca 2 Niveles en los Sistemas Operativos USUARIOS PROGRAMAS DEL SISTEMA INTERPRETE DE COMANDOS UTILIDADES."

Presentaciones similares


Anuncios Google