El núcleo de Linux ofrece múltiples interfaces para código de modo kernel y de espacio de usuario que se utilizan para distintos propósitos y que tienen distintas propiedades por diseño. Existen dos tipos de interfaz de programación de aplicaciones (API) en el núcleo de Linux:
La API de Linux incluye la API de espacio de usuario-núcleo, que permite que el código en el espacio de usuario acceda a los recursos y servicios del sistema del núcleo de Linux. [3] Está compuesta por la interfaz de llamada del sistema del núcleo de Linux y las subrutinas en la biblioteca estándar de C. El foco del desarrollo de la API de Linux ha sido proporcionar las características utilizables de las especificaciones definidas en POSIX de una manera que sea razonablemente compatible, robusta y de alto rendimiento, y proporcionar características útiles adicionales no definidas en POSIX, al igual que las API de espacio de usuario-núcleo de otros sistemas que implementan la API POSIX también proporcionan características adicionales no definidas en POSIX.
La API de Linux, por elección propia, se ha mantenido estable a lo largo de las décadas mediante una política de no introducir cambios disruptivos; esta estabilidad garantiza la portabilidad del código fuente . [4] Al mismo tiempo, los desarrolladores del kernel de Linux han sido históricamente conservadores y meticulosos a la hora de introducir nuevas llamadas al sistema. [ cita requerida ]
Gran parte del software libre y de código abierto disponible está escrito para la API POSIX. Dado que se destina mucho más desarrollo al núcleo de Linux en comparación con otras combinaciones de núcleo y biblioteca estándar de C compatibles con POSIX, [ cita requerida ] el núcleo de Linux y su API se han ampliado con características adicionales. La programación para la API completa de Linux, en lugar de solo la API POSIX, puede proporcionar ventajas en los casos en que esas características adicionales sean útiles. Ejemplos actuales bien conocidos son udev , systemd y Weston . [5] Personas como Lennart Poettering abogan abiertamente por preferir la API de Linux sobre la API POSIX, donde esto ofrece ventajas. [6]
En FOSDEM 2016, Michael Kerrisk explicó algunos de los problemas percibidos con la API de espacio de usuario del núcleo Linux, describiendo que contiene múltiples errores de diseño al no ser extensible, no ser mantenible, ser excesivamente compleja, tener un propósito limitado, violar estándares e inconsistente. La mayoría de esos errores no se pueden corregir porque al hacerlo se rompería la ABI que el núcleo presenta al espacio de usuario. [7]
La interfaz de llamadas del sistema de un núcleo es el conjunto de todas las llamadas del sistema implementadas y disponibles en un núcleo. En el núcleo de Linux, varios subsistemas, como el Direct Rendering Manager (DRM), definen sus propias llamadas del sistema, todas las cuales forman parte de la interfaz de llamadas del sistema.
Se están debatiendo públicamente diversos problemas relacionados con la organización de las llamadas al sistema del núcleo de Linux. Andy Lutomirski, Michael Kerrisk y otros han señalado algunos problemas . [8] [9] [10] [11]
Una biblioteca estándar de C para Linux incluye contenedores para las llamadas del sistema del núcleo de Linux; la combinación de la interfaz de llamadas del sistema del núcleo de Linux y una biblioteca estándar de C es lo que construye la API de Linux. Algunas implementaciones populares de la biblioteca estándar de C son
Al igual que en otros sistemas tipo Unix , existen capacidades adicionales del kernel Linux que no son parte de POSIX:
futex
(mutex rápido de espacio de usuario), epoll
, splice
, , y han sido exclusivas del kernel de Linux hasta ahora dnotify
.fanotify
inotify
getrandom
se introdujo en la versión 3.17 de la línea principal del kernel de Linux [12]memfd
Fue propuesto por los desarrolladores de kdbus [13]memfd_create
Se fusionó con la línea principal del kernel de Linux en la versión 3.17 del kernel.readahead
Inicia una "lectura anticipada" de archivo en la caché de la página.La DRM ha sido fundamental para el desarrollo y la implementación de controladores de dispositivos gráficos libres y de código abierto bien definidos y de alto rendimiento , sin los cuales no estaría disponible ninguna aceleración de renderizado; solo estarían disponibles los controladores 2D en el servidor X.Org . La DRM se desarrolló para Linux y, desde entonces, también se ha adaptado a otros sistemas operativos. [14]
El término Linux ABI se refiere a una ABI de espacio de usuario y núcleo. La interfaz binaria de aplicación se refiere a los binarios compilados, en código de máquina . Por lo tanto, cualquier ABI de este tipo está vinculada al conjunto de instrucciones . Definir una ABI útil y mantenerla estable es menos responsabilidad de los desarrolladores del núcleo Linux o de los desarrolladores de la biblioteca C de GNU, y más tarea de las distribuciones Linux y los proveedores de software independientes (ISV) que desean vender y brindar soporte para su software propietario como binarios solo para una única ABI de Linux, en lugar de brindar soporte para múltiples ABI de Linux.
Se debe definir una ABI para cada conjunto de instrucciones, como x86 , x86-64 , MIPS , ARMv7-A (32 bits), ARMv8-A (64 bits), etc. con el orden de bytes , si ambos son compatibles.
Debe ser posible compilar el software con diferentes compiladores según las definiciones especificadas en la ABI y lograr una compatibilidad binaria total. Los compiladores que son software libre y de código abierto son, por ejemplo, GNU Compiler Collection , LLVM / Clang .
Existen muchas API internas del núcleo que permiten que los subsistemas del núcleo interactúen entre sí. Se mantienen bastante estables, pero no hay garantía de estabilidad. Una API interna del núcleo se puede cambiar cuando una nueva investigación o nuevos conocimientos indiquen esa necesidad; todas las modificaciones y pruebas necesarias deben ser realizadas por el autor.
El núcleo Linux es un núcleo monolítico, por lo que los controladores de dispositivos son componentes del núcleo. Para aliviar la carga de las empresas que mantienen sus controladores de dispositivos (propietarios) fuera del árbol principal del núcleo, se han solicitado repetidamente API estables para los controladores de dispositivos. Los desarrolladores del núcleo Linux han negado repetidamente garantizar API estables en el núcleo para los controladores de dispositivos. Garantizar esto habría hecho tambalear el desarrollo del núcleo Linux en el pasado y lo seguirá haciendo en el futuro y, debido a la naturaleza del software libre y de código abierto, no es necesario. Por lo tanto, por elección propia, el núcleo Linux no tiene una API estable en el núcleo. [15]
Dado que no hay API estables dentro del núcleo, no puede haber ABI estables dentro del núcleo. [16]
En muchos casos de uso, la API de Linux se considera de nivel demasiado bajo, por lo que se deben utilizar API de mayor abstracción. Las API de nivel superior se deben implementar sobre las API de nivel inferior. Ejemplos:
un cambio hace que los programas de usuario dejen de funcionar, es un error del kernel. NUNCA culpamos a los programas de usuario.
De hecho, según mi forma de ver las cosas, la
API de Linux
ha estado asumiendo el papel de la
API de POSIX
y Linux es el punto focal de todo el desarrollo de software libre. Debido a eso, solo puedo recomendar a los desarrolladores que intenten hackear solo con Linux en mente y experimenten la libertad y las oportunidades que esto les ofrece. Entonces, consiga una copia de
The Linux Programming Interface
, ignore todo lo que dice sobre la compatibilidad
con POSIX
y hackee su increíble software Linux. ¡Es bastante reconfortante!