¿Qué se entiende por "una llamada al sistema" si no es la implementación en el lenguaje de programación?


14

Me gustaría entender el término "llamada al sistema". Estoy familiarizado con que las llamadas al sistema se utilizan para obtener servicios del núcleo de una aplicación de espacio de usuario.

La parte con la que necesito aclaración es la diferencia entre una "llamada al sistema" y una "implementación en C de la llamada al sistema".

Aquí hay una cita que me confunde:

En sistemas tipo Unix, esa API generalmente es parte de una implementación de la biblioteca C (libc), como glibc, que proporciona funciones de envoltorio para las llamadas del sistema, a menudo denominadas de la misma manera que las llamadas del sistema que llaman

¿Qué son las "llamadas al sistema que llaman"? ¿Dónde está su fuente? ¿Puedo incluirlos directamente en mi código?

¿Es la "llamada del sistema" en un sentido genérico solo una interfaz POSIX definida, pero para ver realmente la implementación, uno podría examinar la fuente C y ver cómo funciona realmente la comunicación del espacio de usuario al núcleo?

Nota de fondo: estoy tratando de entender si, al final, cada función c termina interactuando con dispositivos de /dev.

Respuestas:


21

Las llamadas al sistema en sí son un concepto. Representan acciones que los procesos pueden pedirle al núcleo que realice.

Esas llamadas al sistema se implementan en el núcleo del sistema tipo UNIX. Esta implementación (escrita en C y en asm para partes pequeñas) realmente realiza la acción en el sistema.

Luego, los procesos utilizan una interfaz para solicitar al sistema la ejecución de las llamadas del sistema. Esta interfaz está especificada por POSIX. Este es un conjunto de funciones de la biblioteca estándar de C. En realidad son envoltorios, pueden realizar algunas comprobaciones y luego llamar a una función específica del sistema en el núcleo que le indica que haga las acciones requeridas por la llamada al sistema. Y el truco es que esas funciones que son la interfaz se denominan de la misma manera que el sistema se llama a sí mismas y a menudo se las llama directamente "llamadas del sistema".

Puede llamar a la función en el núcleo que realiza la llamada al sistema directamente a través del mecanismo específico del sistema. El problema es que hace que su código no sea portátil.

Entonces, una llamada al sistema es:

  • un concepto, una secuencia de acción realizada por el núcleo para ofrecer un servicio a un proceso de usuario
  • la función de la biblioteca estándar de C que debe usar en su código para obtener este servicio del núcleo.

1
¿Tiene un ejemplo de la "función de envoltura" y una llamada real al sistema? (rutas de archivos en Linux o enlaces a fuentes)
TheMeaningfulEngineer

3
Por ejemplo, esta es la implementación de la getpidllamada del sistema en el kernel de Linux: lxr.free-electrons.com/source/kernel/timer.c?v=2.6.35#L1337 . Y esta es la función de contenedor en la biblioteca estándar GNU C glibc-2.19: fossies.org/dox/glibc-2.19/… .
lgeorget

@Igeorget: tus enlaces ya no funcionan. Enlace actualizado para la implementación del kernel: github.com/torvalds/linux/blob/… . No pude encontrar qué hace glibc en estos días, ese código es imposible de navegar.
rchard2scout

6

Una llamada al sistema es una manera de pedirle a su sistema operativo (kernel) que realice alguna operación en nombre de su programa, que el programa no puede hacer por sí mismo (o simplemente es un inconveniente). La razón para no poder realizar alguna operación es normalmente que permitir que un programa aleatorio las haga puede comprometer la integridad del sistema, como hacer E / S (directamente a la RAM, sobrescribiendo cualquier cosa).

POSIX define una interfaz para programas, ciertas funciones que su programa puede llamar. Algunos de ellos se traducen más o menos directamente a las llamadas al sistema, otros requieren más elaboración. Es el tiempo de ejecución para su lenguaje, por ejemplo, la biblioteca C, que es responsable de ofrecer la interfaz POSIX, y de empaquetar argumentos y recibir los resultados de vuelta a la persona que llama.

Los sistemas Unixy ofrecen interfaces POSIX más o menos directamente como llamadas del sistema. Por lo general, hay una manera de invocar llamadas del sistema directamente, busque syscall(2)los detalles sobre cómo usar esta función en Linux.


1
Tocas un punto importante que las otras respuestas simplemente ignoran. Cualquier función que un programador razonablemente capaces podía escribir por sí mismo (como strlen, strcpy, sqrt, y qsort) puede ser y probablemente está en el espacio de usuario, cargado de una biblioteca. (Principalmente libc; funciones matemáticas como sqrty las funciones trigonométricas e hiperbólicas probablemente están en libm, la biblioteca matemática.)… (Continuación)
Scott

1
(continuación) ... Pero no hay forma en que un usuario puede escribir su propia fork, killo openfunción, ya que estas requieren acceso al espacio del núcleo del sistema operativo de memoria (por ejemplo, la tabla de procesos) o instrucciones privilegiadas (por ejemplo, E / S). Por lo tanto, el código que realiza estas funciones debe estar en el núcleo del sistema operativo; por lo tanto, funciones del sistema o llamadas del sistema.
Scott

5

Claro, vamos a hacer ¿cuántas-direcciones-podemos-mirar-a-este-elefante? cosa.

La llamada real del sistema es, en su programa integrado, la instrucción de la máquina que activa la escalada de privilegios al modo kernel, y en el núcleo mismo es el código que invoca la instrucción. El código libc (y cada tiempo de ejecución de idioma) configura los registros de la máquina y los parámetros en almacenamiento donde el código del núcleo espera encontrarlos, que pueden ser lugares decididamente extraños debido a restricciones en las instrucciones de esa máquina.

Una vez en el código del sistema operativo, hay un poco de desenrollado de imagen especular de las cosas específicas de la máquina que hizo el tiempo de ejecución del usuario y luego una llamada de subrutina perfectamente normal.
Si desea ver exactamente cómo funciona esto en un sistema operativo a gran escala, extraiga la fuente del núcleo ( git clone https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/) y haga, por ejemplo git grep -i system\ call. Tire de la fuente glibc y haga lo mismo.


Es cierto, pero hurgar en Linux o glibc es un poco pesado ...
vonbrand

3

En Linux, al menos, el mecanismo de llamada del sistema funciona en la mayoría de las arquitecturas al colocar algunos datos con formato específico (generalmente algún tipo de estructura) en algunos registros o direcciones de memoria predefinidas.

Sin embargo, el problema surge al obligar a la CPU a hacer el cambio al espacio del kernel para que pueda ejecutar el código del kernel privilegiado para atender la llamada. Esto se hace forzando una falla de algún tipo (una falla que es una división entre 0, un desbordamiento indefinido o una falla predeterminada, etc.) que obliga al núcleo a asumir la ejecución para manejar la falla.

Normalmente, el kernel maneja las fallas al eliminar el proceso causante o al ejecutar un controlador proporcionado por el usuario. Sin embargo, en el caso de una llamada al sistema, en su lugar, verificará los registros predefinidos y las ubicaciones de memoria y, si contienen una solicitud de llamada al sistema, la ejecutará utilizando los datos proporcionados por el proceso del usuario en la estructura en memoria. Esto generalmente debe hacerse con un ensamblaje especialmente diseñado a mano y para facilitar el uso de la llamada al sistema para el usuario, la biblioteca C del sistema tiene que envolverlo como una función. Para obtener una interfaz de nivel inferior, visite http://man7.org/linux/man-pages/man2/syscall.2.html para obtener información sobre cómo funcionan las llamadas al sistema y cómo puede llamar sin un contenedor C.

Esto tiene una simplificación excesiva, no es cierto en todas las arquitecturas (mips tiene una instrucción especial de syscall) y no necesariamente funciona igual en todos los sistemas operativos. Aún así, si tiene algún comentario o pregunta, por favor pregunte.

Enmendado: Tenga en cuenta que, con respecto a su comentario sobre cosas en / dev /, esta es en realidad una interfaz de nivel superior para el núcleo, no una inferior. Estos dispositivos realmente usan (aproximadamente) 4 syscalls debajo. Escribirles es lo mismo que escribir una llamada al sistema, leer una llamada a la lectura, abrirlos / cerrarlos equivalentes a las llamadas al sistema abiertas y cerradas y ejecutar un ioctl provoca una llamada al sistema ioctl especial que en sí misma es una interfaz para acceder a una de las muchas ioctl del sistema llamadas (llamadas especiales, generalmente específicas del dispositivo con un uso demasiado limitado para escribir una llamada de sistema completa para ellas).


1

Cada llamada al sistema tiene un número entero asociado. Este número entero es una función del valor de retorno de la llamada al sistema, el número de argumentos a la llamada del sistema y el tipo de argumentos. Este número de llamada del sistema no es más que un desplazamiento en el vector de llamada del sistema global, este vector al que solo se puede acceder en modo privilegiado contiene un puntero a los controladores apropiados. El proceso al invocar una llamada al sistema, se generaría una interrupción de software (interrupción de captura), por lo tanto, se ejecutaría un controlador de trampa que determina qué llamada del sistema se debe invocar. Luego, el núcleo copiará los argumentos de la llamada al sistema pasada por el usuario que está en la pila en los registros del procesador, y al completar el servicio solicitado, los datos se volverán a copiar en la pila desde los registros del procesador. Esta es una de las razones por las cuales hay argumentos limitados para las llamadas al sistema,


Cada llamada (operación) se identifica internamente por un número, verdadero. Pero el número depende de la operación , no del valor de retorno ni del número de argumentos. Una explicación de cómo solía funcionar desde userland en x86 está aquí
vonbrand
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.