La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Lic.Graciela De Luca UNLAM

Presentaciones similares


Presentación del tema: "Lic.Graciela De Luca UNLAM"— Transcripción de la presentación:

1 Lic.Graciela De Luca UNLAM
LLAMADAS AL SISTEMA Lic.Graciela De Luca UNLAM

2 Niveles en los Sistemas Operativos
USUARIOS PROGRAMAS DEL SISTEMA UTILIDADES PARA ARCHIVOS UTILIDADES PARA PROCESOS INTERPRETE DE COMANDOS LLAMADAS AL SISTEMA SISTEMA OPERATIVO 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 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 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 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 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); 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] El número de la interrupción software esta definido por la constante SYSCALL_VECTOR [include/asm-i386/hw_irq.h#L19] 916 void __init trap_init (void) 917 { ... 922 923 set_trap_gate(0,&divide_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); ... 943 944 set_system_gate(SYSCALL_VECTOR,&system_call); 963 } 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. VALORES DE SALIDA En el registro %eax se devuelve el código de retorno. Lic.Graciela De Luca

10 Interfaz ofrecida al programador (API)
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 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 : Una parte inicial que prepara los parámetros del servicio, tal como los espera el SO La instrucción INT 0x80 que realiza el paso al SO Una parte final que recoge los parámetros de contestación del SO para devolverlos al programa que hizo la llamada Lic.Graciela De Luca

12 Proceso de llamada 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) 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. 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). 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. 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). 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. 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) 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 L545 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. Lic.Graciela De Luca

21 Lic.Graciela De Luca

22 Dentro de system_call (entry.S )
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_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 Lic.Graciela De Luca

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

24 Para acceder a los campos de la estructura
4º Se verifica si el proceso padre está monitorizando este proceso (#198 ), en cuyo caso se ejecuta el código tracesys. 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] Se puede ver la correspondencia en la propia estructura sched.h 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. 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 [ ]) Lic.Graciela De Luca

26 6º Se llama a la función que sirve la llamada pedida: 202 call
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. 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]. 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). 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]) 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 [ ] 100 #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; 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. Lic.Graciela De Luca

29 Lic.Graciela De Luca

30 En nuestro caso, la macro SAVE_ALL (entry
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) Si llamamos a una función C, ésta se comportará como si otra función en C le hubiera pasado los parámetros. 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]. 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 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. Lic.Graciela De Luca

32 sys_kill(int pid, int sig)
979 { 980 struct siginfo info; 981 982 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; 987 988 return kill_something_info(sig, &info, pid); 989 } 990 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. 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]. Este código lleva a cabo algunas comprobaciones antes de volver a modo usuario. 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 [ ]) reschedule: call SYMBOL_NAME(schedule) # test jmp ret_from_sys_call 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 ] Lic.Graciela De Luca

37 216 testl $(VM_MASK),EFLAGS(%esp) 217 movl %esp,%eax
213 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 Lic.Graciela De Luca

38 Finalmente se restauran todos los registros con RESTORE_ALL entry
Finalmente se restauran todos los registros con RESTORE_ALL entry.S#L100 (incluido %eax ) 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. Lic.Graciela De Luca

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

41 FIN Lic.Graciela De Luca

42 96 movl $(__KERNEL_DS),%edx; \ 97 movl %edx,%ds; \
85 #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; volver Lic.Graciela De Luca

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


Descargar ppt "Lic.Graciela De Luca UNLAM"

Presentaciones similares


Anuncios Google