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 kernel 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 ), creación y ejecución de nuevos procesos y comunicación con servicios integrales del kernel , 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 los procesos del espacio de usuario , mientras que en algunos sistemas, OS / 360 y sus sucesores, por ejemplo, el código del sistema privilegiado también emite llamadas al sistema. [1]
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 privilegios bajo los cuales se puede ejecutar el software: un programa generalmente se limita a su propio espacio de direcciones para que no pueda acceder o modificar otros programas en ejecución o el sistema operativo en sí, y generalmente se le impide manipular directamente dispositivos de hardware (por ejemplo, el búfer de tramas o dispositivos de red ).
Sin embargo, muchas aplicaciones necesitan acceso a estos componentes, por lo que el sistema operativo pone a disposición las llamadas al sistema para proporcionar implementaciones seguras y bien definidas para tales 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 concede el servicio, el núcleo 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
Generalmente, los sistemas proporcionan una biblioteca o API que se encuentra entre los programas normales y el sistema operativo. En sistemas similares a Unix, esa API suele ser parte de una implementación de la biblioteca C (libc), como glibc , que proporciona funciones contenedoras para las llamadas al sistema, a menudo denominadas igual que las llamadas al sistema que invocan. En Windows NT , esa API es parte de la API nativa , en la biblioteca ntdll.dll ; se trata de 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 al sistema, además de hacer que la llamada al sistema sea más modular . Aquí, la función principal del contenedor es colocar todos los argumentos que se pasarán a la llamada al 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 manera, 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 causa un cambio al modo kernel y usualmente es una llamada de subrutina normal (usando, por ejemplo, una instrucción de ensamblaje "CALL" en algunas arquitecturas de conjuntos de instrucciones (ISA)). La llamada al sistema real transfiere el control al kernel (y es más dependiente de la implementación y de la plataforma que la llamada a 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 las llamadas al sistema fork
y exec
. Hacer la llamada al sistema directamente en el código de la aplicación es más complicado y puede requerir el uso de un código ensamblador incrustado (en C y C ++ ), así como el conocimiento de la interfaz binaria de bajo nivel para la operación de la llamada al sistema, que puede estar sujeta a cambios. a lo largo del tiempo y, por tanto, no formar 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 intermediaria. En exokernels, las bibliotecas protegen las aplicaciones de usuario de la API del kernel de muy bajo nivel y proporcionan abstracciones y administración de recursos .
OS / 360 y DOS / 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 un momento 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 se podían ejecutar directamente mediante programas de lenguaje de alto nivel, sino que requerían una subrutina contenedora de lenguaje ensamblador que se pudiera llamar. Desde entonces, IBM ha añadido muchos servicios que pueden ser llamadas desde lenguajes de alto nivel, por ejemplo en, z / OS y z / VSE .
Ejemplos y herramientas
En Unix , Unix y otros POSIX sistemas operativos según norma, las llamadas al sistema son populares open
, read
, write
, close
, wait
, exec
, fork
, exit
, y kill
. Muchos sistemas operativos modernos tienen cientos de llamadas al sistema. Por ejemplo, Linux y OpenBSD tienen cada uno más de 300 llamadas diferentes, [2] [3] NetBSD tiene cerca de 500, [4] FreeBSD tiene más de 500, [5] Windows 7 tiene cerca de 700, [6] mientras que Plan 9 tiene 51. [7]
Herramientas como strace , ftrace y truss permiten que un proceso se ejecute desde el inicio e informan todas las llamadas al sistema que el proceso invoca, 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 viola los permisos de el usuario. Esta habilidad especial del programa generalmente también se implementa con una llamada al sistema, por ejemplo, strace se implementa con 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 kernel, 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 trampa de software . Interrumpe el control de transferencia 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 independientemente por AMD e Intel , respectivamente, pero en esencia hacen lo mismo). Estas son instrucciones de transferencia de control "rápidas" 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. [8] Linux 2.5 comenzó a usar esto en el x86 , donde estaba disponible; anteriormente usaba la INT
instrucción, donde el número de llamada al sistema se colocaba en el EAX
registro antes de que se ejecutara la interrupción 0x80. [9] [10]
Un mecanismo más antiguo es la puerta de llamada ; originalmente utilizado en Multics y posterior, 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 [11] ) que usa la segmentación de memoria x86 y la falta de portabilidad resultante que causa. , y existencia de las instrucciones más rápidas mencionadas anteriormente.
Para la arquitectura IA-64 , EPC
se usa la instrucción (Ingresar código privilegiado). Los primeros ocho argumentos de la llamada al sistema se pasan en registros y el resto se pasa a la pila.
En el IBM System / 360 de la familia de mainframe, y sus sucesores, una instrucción de Supervisor de llamadas ( SVC ), con el número de la instrucción en lugar de en un registro, implementa una llamada al sistema para instalaciones heredadas en la mayoría de [a] propios sistemas operativos de IBM y para todas las llamadas al sistema en Linux. En los propios sistemas operativos de IBM, la instrucción Program Call (PC) se utiliza para instalaciones más nuevas. En particular, la PC se utiliza cuando la persona que llama puede estar en modo de bloqueo de solicitud de servicio (SRB).
El PDP-11 minicomputadora utilizó la EMT y Instrucciones de IOT , que, de forma similar a IBM System / 360 SVC y x86 INT , ponga 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ó el CHMK , CHME y Instrucciones CHMS para realizar llamadas al sistema a código privilegiado en varios niveles; el código es un argumento para la instrucción.
Categorías de llamadas al sistema
Las llamadas al sistema se pueden agrupar aproximadamente en seis categorías principales: [12]
- Control de procesos
- proceso de creación (por ejemplo,
fork
en sistemas similares a Unix oNtCreateProcess
en la API nativa de Windows NT ) - terminar el proceso
- cargar , ejecutar
- obtener / establecer atributos de proceso
- esperar el tiempo, esperar el evento, señalizar el evento
- asignar y liberar memoria
- proceso de creación (por ejemplo,
- Gestión de archivos
- crear archivo, eliminar archivo
- abierto cerrado
- leer, escribir, reposicionar
- obtener / establecer atributos de archivo
- Gestión de dispositivos
- solicitar dispositivo, liberar dispositivo
- leer, escribir, reposicionar
- obtener / establecer atributos de dispositivo
- conectar o desconectar dispositivos de forma lógica
- Mantenimiento de información
- obtener / configurar la información total del sistema (incluida la hora, la fecha, el nombre de la computadora, la empresa, etc.)
- obtener / establecer metadatos de proceso, archivo o dispositivo (incluido el autor, el abridor, la fecha y hora de creación, etc.)
- Comunicación
- crear, eliminar conexión de comunicación
- enviar, recibir mensajes
- información del estado de la transferencia
- conectar o desconectar dispositivos remotos
- Proteccion
- 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 un cambio de contexto de proceso , aunque sí ocurre un cambio de contexto de privilegio . El hardware ve el mundo en términos del modo de ejecución de acuerdo con el registro de estado del procesador , y los procesos son una abstracción proporcionada por el sistema operativo. Generalmente, una llamada al sistema no requiere un cambio de contexto a otro proceso; en su lugar, se procesa en el contexto de cualquier proceso que lo invoque. [13] [14]
En un proceso multiproceso , las llamadas al sistema se pueden realizar desde múltiples subprocesos . El manejo de tales llamadas depende del diseño del kernel del sistema operativo específico y del entorno de ejecución de la aplicación. La siguiente lista muestra modelos típicos seguidos por sistemas operativos: [15] [16]
- Modelo de muchos a uno : todas las llamadas al sistema desde cualquier hilo de usuario en un proceso son manejadas por un solo hilo a nivel de kernel. Este modelo tiene un serio inconveniente: cualquier llamada al sistema de bloqueo (como esperar la entrada del usuario) puede congelar todos los demás subprocesos. Además, dado que solo un subproceso puede acceder al kernel a la vez, este modelo no puede utilizar varios núcleos de procesador.
- Modelo uno a uno : cada hilo de usuario se adjunta a un hilo de nivel de kernel distinto durante una llamada al sistema. Este modelo resuelve el problema anterior de bloquear llamadas al sistema. Se encuentra en todas las principales distribuciones de Linux , macOS , iOS , versiones recientes de Windows y Solaris .
- Modelo de muchos a muchos : en este modelo, un grupo de subprocesos de usuario se asigna a un grupo de subprocesos del kernel. Todas las llamadas al sistema de un grupo de subprocesos de usuario son manejadas por los subprocesos en su correspondiente grupo de subprocesos del kernel .
- Modelo híbrido : este modelo implementa modelos de muchos a muchos y uno a uno, según la elección realizada por el kernel. Se encuentra en versiones antiguas de IRIX , HP-UX y Solaris .
Ver también
- API del kernel de Linux
- VDSO
Notas
- ^ El componente CP de CP-67 y VM utiliza la instrucción Diagnose (DIAG) como una CALL de hipervisor (HVC) desde una máquina virtual a CP.
Referencias
- ^ IBM (marzo de 1967). "Escribir rutinas de SVC". IBM System / 360 Operating System System Programmer's Guide (PDF) . Tercera edicion. págs. 32–36. C28-6550-2.
- ^ "syscalls (2) - página de manual de Linux" .
- ^ OpenBSD (14 de septiembre de 2013). "Nombres de llamadas al sistema (kern / syscalls.c)" . Referencia cruzada BSD .
- ^ NetBSD (17 de octubre de 2013). "Nombres de llamadas al sistema (kern / syscalls.c)" . Referencia cruzada BSD .
- ^ "FreeBSD syscalls.c, la lista de nombres e ID de syscall" .
- ^ Autor: Mateusz "j00ru" Jurczyk (5 de noviembre de 2017). "Tabla de llamadas del sistema Windows WIN32K.SYS (NT / 2000 / XP / 2003 / Vista / 2008/7/8/10)" .
- ^ "Plan 9 sys.h, la lista de nombres e ID de syscall" .
- ^ "SYSENTER (OSDev wiki)" .
- ^ Anónimo (19 de diciembre de 2002). "Linux 2.5 obtiene vsyscalls, soporte de sysenter" . KernelTrap . Consultado el 1 de enero de 2008 .
- ^ Manu Garg (2006). "Mecanismo de llamada del sistema basado en Sysenter en Linux 2.6" .
- ^ "Liberation: referencia de conjunto de instrucciones x86" . renejeschke.de . Consultado el 4 de julio de 2015 .
- ^ Silberschatz, Abraham (2018). Conceptos del sistema operativo . Peter B. Galvin; Greg Gagne (10ª ed.). Hoboken, Nueva Jersey: Wiley. pag. 67. ISBN 9781119320913. OCLC 1004849022 .
- ^ Bach, Maurice J. (1986), El diseño del sistema operativo UNIX , Prentice Hall, págs. 15-16.
- ^ Elliot, John (2011). "Discusión de la implementación de llamadas al sistema en ProgClub, incluida la cita de Bach 1986" .
- ^ "Hilos" .
- ^ "Modelos de roscado" (PDF) .
enlaces externos
- Listado / referencia de llamadas al sistema Linux de 64 bits Hasta la versión 4.20 del kernel
- Referencia de llamada al sistema Linux Referencia de llamada al sistema actualizada para el kernel de Linux 2.6.35.4, incluye referencias de estructura de datos y registros. También para el kernel de Linux 4.14 de 64 bits y 32 bits .
- Una lista de llamadas al sistema modernas similares a Unix
- Mapa interactivo del kernel de Linux con las principales funciones y estructuras de la API, versión PDF
- Llamadas al sistema Linux: llamadas al sistema para el kernel 2.2 de Linux , con convenciones de llamadas IA-32
- Cómo funcionan las llamadas del sistema en Linux / i86 (1996, basado en el kernel 1993 0.99.2)
- Mecanismo de llamada del sistema basado en Sysenter en Linux 2.6 (2006)
- Comando de kernel utilizando llamadas al sistema Linux , IBM developerWorks
- Choudhary, Amit; CÓMO para implementar una llamada al sistema en Linux 2.6
- Jorrit N. Herder, Herbert Bos, Ben Gras, Philip Homburg, y Andrew S. Tanenbaum, la programación del sistema modular de Minix 3 , ; entrada: 31, no. 2 (abril de 2006); 19-28, consultado el 5 de marzo de 2018
- Un shell Unix abierto simple en lenguaje C : ejemplos de llamadas al sistema en Unix
- Dentro de la API nativa - Windows NT nativo API , incluyendo las llamadas al sistema
- Gulbrandsen, John; Optimización de llamadas al sistema con la instrucción SYSENTER, CodeGuru.com, 8 de octubre de 2004
Este artículo se basa en material extraído del Diccionario gratuito de informática en línea antes del 1 de noviembre de 2008 e incorporado bajo los términos de "renovación de licencias" de la GFDL , versión 1.3 o posterior.