Llamada al sistema

Forma en que los programas pueden acceder a los servicios del kernel

Una descripció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 del usuario.

En informática, una llamada al sistema (comúnmente abreviada como syscall ) es la forma programática en la que un programa informático solicita un servicio al sistema operativo [a] 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 del espacio de usuario , mientras que en algunos sistemas, OS/360 y sucesores por ejemplo, el código de sistema privilegiado también emite llamadas al sistema. [1]

En el caso de los sistemas integrados , las llamadas del sistema normalmente no cambian el modo de privilegio de la CPU.

Privilegios

La arquitectura de la mayoría de los procesadores modernos, con 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 suele estar limitado a su propio espacio de direcciones , de modo que no puede acceder ni modificar otros programas en ejecución ni el propio sistema operativo, y normalmente se le impide manipular directamente dispositivos de hardware (por ejemplo, el búfer de trama o los dispositivos de red ).

Sin embargo, muchas aplicaciones necesitan tener acceso a estos componentes, por lo que el sistema operativo pone a disposición llamadas del sistema para proporcionar implementaciones seguras y bien definidas para dichas operaciones. El sistema operativo se ejecuta en el nivel más alto de privilegio y permite que las aplicaciones soliciten servicios a través de llamadas del 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 núcleo, que determina si se debe conceder el servicio solicitado al programa que realiza la llamada. Si se concede el servicio, el núcleo ejecuta un conjunto específico de instrucciones sobre las que el programa que realiza la llamada no tiene control directo, devuelve el nivel de privilegio al del programa que realiza la llamada y luego devuelve el control al programa que realiza la llamada.

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 tipo Unix , esa API suele ser parte de una implementación de la biblioteca C (libc), como glibc , que proporciona funciones contenedoras para las llamadas del sistema, a menudo denominadas igual que las llamadas del 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 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 quizás también en la pila de llamadas ), y también establecer un número de llamada del sistema único para que el núcleo llame. De esta manera, la biblioteca, que existe entre el SO y la aplicación, aumenta la portabilidad .

La llamada a la función de biblioteca en sí no provoca un cambio al modo kernel y suele ser una llamada de subrutina normal (utilizando, 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 depende más de la implementación y de la plataforma que la llamada a la biblioteca que la abstrae). Por ejemplo, en sistemas tipo Unix , forky execveson funciones de biblioteca de C que a su vez ejecutan instrucciones que invocan las llamadas al sistema forky exec. Realizar 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++ ), así como el conocimiento de la interfaz binaria de bajo nivel para la operación de llamada al sistema, que puede estar sujeta a cambios con el tiempo y, por lo tanto, no ser parte de la interfaz binaria de la aplicación ; las funciones de biblioteca están pensadas para abstraer esto.

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

Los sistemas operativos 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 , [b] aunque hay algunos servicios con un enlace de llamada. Esto refleja su origen en una época en la que la programación en lenguaje ensamblador era más común que el uso de lenguajes de alto nivel . Por lo tanto, las llamadas al sistema de IBM no eran ejecutables directamente por programas en lenguaje de alto nivel, sino que requerían una subrutina contenedora en lenguaje ensamblador invocable. Desde entonces, IBM ha añadido muchos servicios que se pueden invocar desde lenguajes de alto nivel en, 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 una Llamada de programa (PC).

Ejemplos y herramientas

En Unix , sistemas operativos similares a Unix y otros compatibles con POSIX , las llamadas al sistema más populares son 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 tiene cerca de 2000, divididas entre llamadas al sistema win32k (gráficas) y ntdll (núcleo) [6] mientras que Plan 9 tiene 51. [7]

Herramientas como strace , ftrace y truss permiten que un proceso se ejecute desde el inicio y reporte todas las llamadas al sistema que invoca 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 viola los permisos del usuario. Esta capacidad 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 desde el 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 de software o una trampa . Las interrupciones transfieren el control al núcleo del sistema operativo , por lo que el software simplemente necesita configurar algún registro con el número de llamada al sistema necesario y ejecutar la interrupción de software.

Esta es la única técnica que se ofrece 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/ SYSRETy 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 núcleo para una llamada del 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 INTinstrucción, donde el número de llamada del 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 compuerta de llamada ; originalmente utilizada en Multics y posteriormente, por ejemplo, véase compuerta de llamada en Intel x86 . Permite que un programa llame a una función del núcleo 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 utiliza la segmentación de memoria x86 y la falta de portabilidad resultante que causa, y la existencia de las instrucciones más rápidas mencionadas anteriormente.

Para la arquitectura IA-64 , EPCse utiliza 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 la familia de mainframes 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 una llamada de sistema para funciones heredadas en la mayoría de los sistemas operativos propios de IBM y para todas las llamadas de sistema en Linux. En versiones posteriores de MVS, IBM utiliza la instrucción de llamada de programa (PC) para muchas funciones más nuevas. En particular, PC se utiliza cuando el llamador puede estar en modo de bloque de solicitud de servicio (SRB).

La minicomputadora PDP-11 utilizaba las instrucciones EMT , TRAP e IOT , que, de manera similar a las SVC del IBM System/360 y a las INT del x86 , colocaban el código en la instrucción; generaban interrupciones a direcciones específicas, transfiriendo el control al sistema operativo. El sucesor de 32 bits de la serie PDP-11, VAX, utilizaba las instrucciones CHMK , CHME y CHMS para realizar llamadas del sistema a código privilegiado en varios niveles; el código es un argumento de la instrucción.

Categorías de llamadas al sistema

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

  1. Control de procesos
  2. Gestión de archivos
    • crear archivo, eliminar archivo
    • abrir, cerrar
    • leer, escribir, reposicionar
    • Obtener/establecer atributos de archivo
  3. Gestión de dispositivos
    • solicitar dispositivo, liberar dispositivo
    • leer, escribir, reposicionar
    • Obtener/establecer atributos del dispositivo
    • conectar o desconectar dispositivos de forma lógica
  4. Mantenimiento de la información
    • Obtener/establecer información total del sistema (incluyendo hora, fecha, nombre de la computadora, empresa, etc.)
    • Obtener/establecer metadatos de proceso, archivo o dispositivo (incluido autor, abridor, fecha y hora de creación, etc.)
  5. Comunicación
    • crear, eliminar conexión de comunicación
    • enviar, recibir mensajes
    • información del estado de la transferencia
    • conectar o desconectar 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 tipo 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í se produce 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. 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 la invoque. [13] [14]

En un proceso multiproceso , las llamadas al sistema pueden realizarse desde varios subprocesos . El manejo de dichas llamadas depende del diseño del núcleo del sistema operativo específico y del entorno de ejecución de la aplicación. La siguiente lista muestra los modelos típicos que siguen los sistemas operativos: [15] [16]

  • Modelo de varios a uno : todas las llamadas del sistema de cualquier subproceso de usuario en un proceso son manejadas por un único subproceso a nivel de núcleo. Este modelo tiene un serio inconveniente: cualquier llamada al sistema que bloquee (como esperar la entrada del usuario) puede congelar todos los demás subprocesos. Además, dado que solo un subproceso puede acceder al núcleo a la vez, este modelo no puede utilizar varios núcleos de procesadores.
  • Modelo uno a uno : cada hilo de usuario se vincula a un hilo distinto a nivel de kernel durante una llamada del sistema. Este modelo resuelve el problema mencionado anteriormente de bloquear las llamadas del sistema. Se encuentra en todas las principales distribuciones de Linux , macOS , iOS y versiones recientes de Windows y Solaris .
  • Modelo de varios a varios : en este modelo, un grupo de subprocesos de usuario se asigna a un grupo de subprocesos de kernel. Todas las llamadas del sistema de un grupo de subprocesos de usuario son manejadas por los subprocesos en su grupo de subprocesos de kernel correspondiente .
  • Modelo híbrido : este modelo implementa tanto modelos de muchos a muchos como de uno a uno, según la elección realizada por el núcleo. Se encuentra en versiones anteriores de IRIX , HP-UX y Solaris .

Véase también

Notas

  1. ^ En sistemas operativos tipo UNIX , las llamadas del sistema se utilizan solo para el núcleo.
  2. ^ En muchos casos, pero no en todos, IBM documentó, por ejemplo, el número SVC y los registros de parámetros.
  3. ^ Los componentes CP de CP-67 y VM utilizan la instrucción Diagnose (DIAG) como una LLAMADA de hipervisor (HVC) desde una máquina virtual a CP.

Referencias

  1. ^ IBM (marzo de 1967). "Writing SVC Routines" (Escritura de rutinas SVC). Guía del programador del sistema operativo IBM System/360 (PDF) . Tercera edición. Págs. 32–36. C28-6550-2.
  2. ^ "syscalls(2) - Página del manual de Linux".
  3. ^ OpenBSD (14 de septiembre de 2013). "Nombres de llamadas del sistema (kern/syscalls.c)". Referencia cruzada de BSD .
  4. ^ NetBSD (17 de octubre de 2013). "Nombres de llamadas del sistema (kern/syscalls.c)". Referencia cruzada de BSD .
  5. ^ "FreeBSD syscalls.c, la lista de nombres e identificaciones de llamadas al sistema".
  6. ^ 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)".{{cite web}}: CS1 maint: nombres numéricos: lista de autores ( enlace )
  7. ^ "sys.h". Plan 9 de Bell Labs . Archivado desde el original el 8 de septiembre de 2023.la lista de nombres e identificaciones de llamadas al sistema.
  8. ^ "SYSENTER". Wiki de OSDev . Archivado desde el original el 8 de noviembre de 2023.
  9. ^ Anónimo (19 de diciembre de 2002). "Linux 2.5 obtiene compatibilidad con vsyscalls y sysenter". KernelTrap . Consultado el 1 de enero de 2008 .
  10. ^ Manu Garg (2006). "Mecanismo de llamada al sistema basado en Sysenter en Linux 2.6".
  11. ^ "Liberation: x86 Instruction Set Reference". renejeschke.de . Consultado el 4 de julio de 2015 .
  12. ^ Silberschatz, Abraham (2018). Conceptos de sistemas operativos . Peter B Galvin; Greg Gagne (10.ª ed.). Hoboken, Nueva Jersey: Wiley. pág. 67. ISBN 9781119320913.OCLC 1004849022  .
  13. ^ Bach, Maurice J. (1986), El diseño del sistema operativo UNIX , Prentice Hall, págs. 15-16.
  14. ^ Elliot, John (2011). "Discusión sobre la implementación de llamadas al sistema en ProgClub, incluida una cita de Bach 1986".
  15. ^ "Hilos".
  16. ^ "Modelos de subprocesamiento" (PDF) .
  • 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 del sistema Linux: llamadas del sistema para el kernel Linux 2.2, con convenciones de llamadas IA-32
  • Cómo funcionan las llamadas del sistema en Linux/i86 (1996, basado en el kernel 0.99.2 de 1993)
  • Mecanismo de llamada al sistema basado en Sysenter en Linux 2.6 (2006)
  • Comando del kernel que utiliza llamadas al sistema Linux, IBM developerWorks
  • Choudhary, Amit; CÓMO implementar una llamada al sistema en Linux 2.6
  • Jorrit N. Herder, Herbert Bos, Ben Gras, Philip Homburg y Andrew S. Tanenbaum, Programación de sistemas modulares en Minix 3, ;login: 31, no. 2 (abril de 2006); 19–28, consultado el 5 de marzo de 2018
  • Un shell Unix simple y abierto en lenguaje C: ejemplos de llamadas al sistema en Unix
  • Dentro de la API nativa: API nativa de Windows NT , incluidas las llamadas del sistema
  • Gulbrandsen, John; Optimización de llamadas al sistema con la instrucción SYSENTER, CodeGuru.com, 8 de octubre de 2004
Obtenido de "https://es.wikipedia.org/w/index.php?title=Llamada_al_sistema&oldid=1242939825"