Llamada al sistema

format_list_bulleted Contenido keyboard_arrow_down
ImprimirCitar
Formas de acceso a los servicios de kernel
Una visión general de alto nivel de la interfaz de llamada del sistema del kernel de Linux, que maneja la comunicación entre sus diversos componentes y el espacio de usuario

En informática, una llamada al sistema (comúnmente abreviada como syscall) es la forma programática en la que un programa de computadora solicita un servicio del sistema operativo en el que se ejecuta.. Esto puede incluir servicios relacionados con el hardware (por ejemplo, acceder a una unidad de disco duro o acceder a la cámara del dispositivo), la creación y ejecución de nuevos procesos y la comunicación con servicios integrales del núcleo, como la programación de procesos. Las llamadas al sistema proporcionan una interfaz esencial entre un proceso y el sistema operativo.

En la mayoría de los sistemas, las llamadas al sistema solo se pueden realizar desde procesos de espacio de usuario, mientras que en algunos sistemas, OS/360 y sucesores, por ejemplo, el código del sistema privilegiado también emite llamadas al sistema.

Privilegios

La arquitectura de la mayoría de los procesadores modernos, con la excepción de algunos sistemas integrados, implica un modelo de seguridad. Por ejemplo, el modelo de anillos especifica múltiples niveles de privilegio bajo los cuales se puede ejecutar el software: un programa generalmente está limitado a su propio espacio de direcciones para que no pueda acceder o modificar otros programas en ejecución o el propio sistema operativo, y generalmente se le impide manipular directamente los dispositivos de hardware (por ejemplo, el búfer de cuadros o los dispositivos de red).

Sin embargo, muchas aplicaciones necesitan acceso a estos componentes, por lo que el sistema operativo pone a disposición las llamadas del sistema para proporcionar implementaciones seguras y bien definidas para dichas operaciones. El sistema operativo se ejecuta al más alto nivel de privilegios y permite que las aplicaciones soliciten servicios a través de llamadas al sistema, que a menudo se inician mediante interrupciones. Una interrupción coloca automáticamente a la CPU en un nivel de privilegio elevado y luego pasa el control al kernel, que determina si el programa que llama debe recibir el servicio solicitado. Si se otorga el servicio, el kernel ejecuta un conjunto específico de instrucciones sobre las cuales el programa que llama no tiene control directo, devuelve el nivel de privilegio al del programa que llama y luego devuelve el control al programa que llama.

La biblioteca como intermediaria

Por lo general, los sistemas proporcionan una biblioteca o API que se encuentra entre los programas normales y el sistema operativo. En los sistemas similares a Unix, esa API suele ser parte de una implementación de la biblioteca C (libc), como glibc, que proporciona funciones de contenedor para las llamadas al sistema, a menudo con el mismo nombre que las llamadas al sistema que invocan. En Windows NT, esa API es parte de la API nativa, en la biblioteca ntdll.dll; esta es una API no documentada utilizada por las implementaciones de la API normal de Windows y utilizada directamente por algunos programas del sistema en Windows. Las funciones contenedoras de la biblioteca exponen una convención de llamada de función ordinaria (una llamada de subrutina en el nivel de ensamblaje) para usar la llamada del sistema, así como para hacer que la llamada del sistema sea más modular. Aquí, la función principal del contenedor es colocar todos los argumentos que se pasarán a la llamada del sistema en los registros del procesador apropiados (y tal vez también en la pila de llamadas), y también establecer un número de llamada del sistema único para que el kernel llame.. De esta forma, la biblioteca, que existe entre el sistema operativo y la aplicación, aumenta la portabilidad.

La llamada a la función de biblioteca en sí misma no provoca un cambio al modo kernel y, por lo general, es una llamada de subrutina normal (usando, por ejemplo, una instrucción de ensamblaje "CALL" en algunas arquitecturas de conjunto de instrucciones (ISA)). La llamada al sistema real transfiere el control al núcleo (y es más dependiente de la implementación y de la plataforma que la llamada de la biblioteca que lo abstrae). Por ejemplo, en sistemas similares a Unix, fork y execve son funciones de biblioteca C que a su vez ejecutan instrucciones que invocan fork y exec llamadas al sistema. Hacer la llamada al sistema directamente en el código de la aplicación es más complicado y puede requerir el uso de código ensamblador integrado (en C y C++), además de requerir conocimiento de la interfaz binaria de bajo nivel para la operación de la llamada al sistema, que puede estar sujeta cambiar con el tiempo y, por lo tanto, no ser parte de la interfaz binaria de la aplicación; las funciones de la biblioteca están destinadas a abstraer esto.

En los sistemas basados en exokernel, la biblioteca es especialmente importante como intermediario. En los exokernels, las bibliotecas protegen las aplicaciones de los usuarios de la API del kernel de muy bajo nivel y proporcionan abstracciones y administración de recursos.

OS/360, DOS/360 y TSS/360 de IBM implementan la mayoría de las llamadas al sistema a través de una biblioteca de macros en lenguaje ensamblador, aunque hay algunos servicios con un enlace de llamadas. Esto refleja su origen en una época en que la programación en lenguaje ensamblador era más común que el uso del lenguaje de alto nivel. Por lo tanto, las llamadas al sistema de IBM no eran ejecutables directamente por programas de lenguaje de alto nivel, sino que requerían una subrutina contenedora de lenguaje ensamblador invocable. Desde entonces, IBM ha agregado muchos servicios a los que se puede llamar desde lenguajes de alto nivel, por ejemplo, z/OS y z/VSE. En la versión más reciente de MVS/SP y en todas las versiones posteriores de MVS, algunas macros de llamadas al sistema generan llamadas de programa (PC).

Ejemplos y herramientas

En Unix, similares a Unix y otros sistemas operativos compatibles con POSIX, las llamadas al sistema populares son open, read, write, cerrar, esperar, ejec, bifurcar, salir y matar. Muchos sistemas operativos modernos tienen cientos de llamadas al sistema. Por ejemplo, Linux y OpenBSD tienen cada uno más de 300 llamadas diferentes, NetBSD tiene cerca de 500, FreeBSD tiene más de 500, Windows tiene cerca de 2000, dividido entre llamadas de sistema win32k (gráfico) y ntdll (núcleo), mientras que Plan 9 tiene 51.

Herramientas como strace, ftrace y truss permiten que un proceso se ejecute desde el principio e informen todas las llamadas al sistema que invoque el proceso, o pueden adjuntarse a un proceso que ya se está ejecutando e interceptar cualquier llamada al sistema realizada por dicho proceso si la operación no lo hace. violar los permisos del usuario. Esta habilidad especial del programa generalmente también se implementa con llamadas al sistema como ptrace o llamadas al sistema en archivos en procfs.

Implementaciones típicas

La implementación de llamadas al sistema requiere una transferencia de control del espacio del usuario al espacio del núcleo, lo que implica algún tipo de característica específica de la arquitectura. Una forma típica de implementar esto es usar una interrupción o captura de software. Las interrupciones transfieren el control al kernel del sistema operativo, por lo que el software simplemente necesita configurar algún registro con el número de llamada del sistema necesario y ejecutar la interrupción del software.

Esta es la única técnica proporcionada para muchos procesadores RISC, pero las arquitecturas CISC como x86 admiten técnicas adicionales. Por ejemplo, el conjunto de instrucciones x86 contiene las instrucciones SYSCALL/SYSRET y SYSENTER/SYSEXIT (estos dos mecanismos fueron creados de forma independiente por AMD e Intel, respectivamente, pero en esencia hacen lo mismo). Estos son "rápidos" instrucciones de transferencia de control que están diseñadas para transferir rápidamente el control al kernel para una llamada al sistema sin la sobrecarga de una interrupción. Linux 2.5 comenzó a usar esto en x86, donde estaba disponible; anteriormente usaba la instrucción INT, donde el número de llamada del sistema se colocaba en el registro EAX antes de que se ejecutara la interrupción 0x80.

Un mecanismo más antiguo es la puerta de llamada; utilizado originalmente en Multics y más tarde, por ejemplo, ver puerta de llamada en Intel x86. Permite que un programa llame a una función del kernel directamente utilizando un mecanismo de transferencia de control seguro, que el sistema operativo configura de antemano. Este enfoque ha sido impopular en x86, presumiblemente debido al requisito de una llamada lejana (una llamada a un procedimiento ubicado en un segmento diferente al segmento de código actual) que utiliza la segmentación de memoria x86 y la consiguiente falta de portabilidad que provoca, y la existencia de las instrucciones más rápidas mencionadas anteriormente.

Para la arquitectura IA-64, se utiliza la instrucción EPC (Introducir código privilegiado). Los primeros ocho argumentos de llamada al sistema se pasan en registros y el resto se pasa en la pila.

En la familia de mainframe IBM System/360 y sus sucesores, una instrucción de llamada de supervisor (SVC), con el número en la instrucción en lugar de en un registro, implementa un llamada al sistema para instalaciones heredadas en la mayoría de los sistemas operativos propios de IBM y para todas las llamadas al sistema en Linux. En versiones posteriores de MVS, IBM usa la instrucción Program Call (PC) para muchas instalaciones más nuevas. En particular, la PC se usa cuando la persona que llama puede estar en el modo Bloque de solicitud de servicio (SRB).

El minicomputer PDP-11 usó el EMT y IOT instrucciones similares al sistema IBM/360 SVC y x86 INT, poner el código en la instrucción; generan interrupciones a direcciones específicas, transfiriendo el control al sistema operativo. El sucesor VAX de 32 bits de la serie PDP-11 utilizó la CHMK, CHME, y CHMS instrucciones para hacer llamadas del sistema al código privilegiado en varios niveles; el código es un argumento a la instrucción.

Categorías de llamadas al sistema

Las llamadas al sistema se pueden agrupar aproximadamente en seis categorías principales:

  1. Control de procesos
    • crear proceso (por ejemplo, fork en sistemas similares a unix, o NtCreateProcess en la API nativa de Windows NT)
    • terminar el proceso
    • Carga, ejecución
    • get/set procesador atributos
    • espera por tiempo, evento de espera, evento de señal
    • asignar y libre memoria
  2. Gestión de archivos
    • crear archivo, eliminar archivo
    • abierto, cerca
    • leer, escribir, reposición
    • atributos de archivo get/set
  3. Gestión de dispositivos
    • dispositivo de petición, dispositivo de liberación
    • leer, escribir, reposición
    • atributos de dispositivo get/set
    • dispositivos de fijación o desprendimiento lógicamente
  4. Mantenimiento de la información
    • get/set total system information (including time, date, computer name, enterprise etc.)
    • get/set proceso, archivo, o metadatos de dispositivos (incluido autor, abrelatador, tiempo de creación y fecha, etc.)
  5. Comunicación
    • crear, eliminar la conexión de comunicación
    • enviar, recibir mensajes
    • información sobre el estado de transferencia
    • adjuntar o desvincular dispositivos remotos
  6. Protección
    • obtener / establecer permisos de archivo

Modo de procesador y cambio de contexto

Las llamadas al sistema en la mayoría de los sistemas similares a Unix se procesan en modo kernel, lo que se logra cambiando el modo de ejecución del procesador a uno más privilegiado, pero no es necesario cambiar el contexto del proceso, aunque un privilegio. El hardware ve el mundo en términos del modo de ejecución según el registro de estado del procesador, y los procesos son una abstracción proporcionada por el sistema operativo. Una llamada al sistema generalmente no requiere un cambio de contexto a otro proceso; en cambio, se procesa en el contexto de cualquier proceso que lo haya invocado.

En un proceso de subprocesos múltiples, las llamadas al sistema se pueden realizar desde varios subprocesos. El manejo de dichas llamadas depende del diseño del kernel del sistema operativo específico y del entorno de tiempo de ejecución de la aplicación. La siguiente lista muestra modelos típicos seguidos por sistemas operativos:

  • Muchos a uno modelo: Todas las llamadas del sistema de cualquier hilo de usuario en un proceso son manejadas por un solo hilo de nivel del núcleo. Este modelo tiene un serio inconveniente: cualquier llamada del sistema de bloqueo (como la entrada pendiente del usuario) puede congelar todos los demás hilos. Además, ya que solo un hilo puede acceder al núcleo a la vez, este modelo no puede utilizar múltiples núcleos de procesadores.
  • Uno a uno modelo: Cada hilo de usuario se une a un hilo de nivel de núcleo distinto durante una llamada del sistema. Este modelo resuelve el problema de bloqueo de llamadas del sistema. Se encuentra en todas las principales distribuciones de Linux, macOS, iOS, versiones recientes de Windows y Solaris.
  • Muchas a muchas personas modelo: En este modelo, una piscina de hilos de usuario se mapea a una piscina de hilos del núcleo. Todas las llamadas del sistema de un grupo de hilos de usuario son manejadas por los hilos en su correspondiente grupo de hilos del núcleo.
  • híbrido modelo: Este modelo implementa tanto muchos como uno a uno de los modelos dependiendo de la elección hecha por el núcleo. Esto se encuentra en versiones antiguas de IRIX, HP-UX y Solaris.

Contenido relacionado

VisiCalc

VisiCalc fue el primer programa de hoja de cálculo para computadoras personales, lanzado originalmente para Apple II por VisiCorp el 17 de octubre de 1979. A...

Hilo (informática)

En informática, un hilo de ejecución es la secuencia más pequeña de instrucciones programadas que puede gestionar de forma independiente un programador...

Codificación Huffman

En informática y teoría de la información, un código Huffman es un tipo particular de código de prefijo óptimo que se usa comúnmente para la...
Más resultados...
Tamaño del texto:
Copiar