¿Por qué la API del módulo de Linux no es compatible con versiones anteriores?

Aug 18 2020

¿Por qué la API del módulo de Linux no es compatible con versiones anteriores? Me frustra encontrar controladores actualizados después de actualizar el kernel de Linux.

Tengo un adaptador inalámbrico que necesita un controlador patentado, pero el fabricante descontinuó este dispositivo hace aproximadamente 7 años. Como el código es muy antiguo y se escribió para Linux 2.6.0.0, no se compila con los kernels de Linux más recientes. He usado muchas distribuciones de Linux pero el mismo problema está en todas partes. Aunque hay un controlador de código abierto distribuido con el kernel de Linux, no funciona. Algunas personas están tratando de modificar el antiguo código propietario para que sea compatible con los últimos kernels de Linux, pero cuando se lanza un nuevo kernel de Linux, lleva meses hacer que el código sea compatible con él. Dentro de ese tiempo, se lanza otra nueva versión. Por esta razón, no puedo actualizar a un nuevo kernel de Linux; a veces ni siquiera puedo actualizar mi distribución.

Respuestas

4 PhilipCouling Aug 18 2020 at 21:28

Greg Kroah-Hartman ha escrito sobre este tema aquí:https://www.kernel.org/doc/html/v4.10/process/stable-api-nonsense.html

Además de algunos detalles técnicos con respecto a la compilación del código C, señala un par de problemas básicos de ingeniería de software que toman su decisión.


Linux Kernel es siempre un trabajo en progreso. Esto sucede por muchas razones:

  • Llegan nuevos requisitos. La gente quiere que su software haga más, es por eso que la mayoría de nosotros actualizamos, queremos las funciones más recientes y mejores. Estos pueden requerir reelaboración del software existente.
  • Se encuentran errores que necesitan corrección, a veces los errores están en el diseño en sí y no se pueden corregir sin una revisión significativa
  • Surgen nuevas ideas y modismos en el mundo del software y las personas encuentran formas mucho más fáciles, elegantes y eficientes de hacer las cosas.

Esto es cierto para la mayoría del software , y cualquier software que no se mantenga tendrá una muerte lenta y dolorosa . Lo que está preguntando es por qué ese viejo código sin mantenimiento todavía no funciona.

¿Por qué no se mantienen las interfaces antiguas?

Para garantizar la compatibilidad con versiones anteriores, sería necesario mantener las interfaces antiguas (a menudo "rotas" e inseguras). Por supuesto, es teóricamente posible hacer esto, excepto que conlleva un costo significativo .

Greg Kroah-Hartman escribe

Si Linux tuviera que asegurarse de que conservará una interfaz de origen estable, se habría creado una nueva interfaz, y la más antigua y rota habría tenido que mantenerse con el tiempo, lo que generaría un trabajo adicional para los [desarrolladores]. Dado que todos los [desarrolladores] de Linux hacen su trabajo en su propio tiempo, no es posible pedir a los programadores que hagan trabajo extra sin obtener ganancias, de forma gratuita.

Aunque Linux es de código abierto, el tiempo del desarrollador para mantenerlo es limitado. Por lo tanto, la mano de obra todavía se puede discutir en términos de "costo". Los desarrolladores tienen que elegir cómo pasan su tiempo:

  • Dedique mucho tiempo a mantener interfaces antiguas, rotas, lentas o inseguras. Esto a veces puede ser el doble o el triple del tiempo que tomó escribir la interfaz en la primera instancia.
  • Deseche las interfaces antiguas y espere que otros mantenedores de software [hagan su trabajo y] mantengan su propio software.

En general, agrupar las interfaces es realmente rentable (para los desarrolladores del kernel) . Si quieres saber por qué los desarrolladores no pasan meses y años de su vida evitando que pagues $10 por un nuevo adaptador wifi... esa es la razón. Recuerde que es rentable en términos de tiempo y dinero para los desarrolladores del kernel, no necesariamente rentable para usted o los fabricantes.

6 telcoM Aug 19 2020 at 21:11

Aunque he contribuido con algunos parches (muy pequeños) al kernel de Linux, no me considero un desarrollador del kernel. Sin embargo, esto es lo que sé:


Un controlador escrito para la versión 2.6.0.0 del kernel es anterior a la eliminación de Big Kernel Lock (BKL) que ocurrió en la versión 2.6.39 del kernel.

El BKL se creó cuando Linux todavía era un sistema operativo de un solo procesador (un solo núcleo, un solo hilo). Tan pronto como se agregó la compatibilidad con SMP, los desarrolladores reconocieron que BKL se convertiría en un gran cuello de botella en algún momento, pero siempre que hubiera solo unos pocos núcleos/subprocesos en el sistema en total, era algo tolerable. Pero primero se convirtió en un problema real para las personas que usaban Linux en supercomputadoras, por lo que el trabajo comenzó a reemplazar todo lo que necesitaba el BKL con mecanismos de bloqueo más detallados o, cuando era posible, con métodos sin bloqueo.

En las computadoras modernas, que pueden tener números de núcleos de dos dígitos en las computadoras de escritorio normales y las computadoras portátiles de alta potencia, y mucho menos en los servidores, también se necesitaría una API del módulo del kernel compatible con versiones anteriores 2.6.0 para implementar BKL.

Si un módulo heredado dice "Quiero tomar el BKL", el resto del kernel no tiene idea de qué planea hacer el módulo con él, por lo que el mecanismo de compatibilidad con versiones anteriores tendría que tomar todos los bloqueos que reemplazaron el BKL. solo para cubrir todas las posibilidades. Eso sería un gran éxito de rendimiento. Y los nuevos métodos sin bloqueo también tendrían que verificar el bloqueo heredado, lo que anula el punto de no tener bloqueo en primer lugar. Por lo tanto, la existencia misma del mecanismo de compatibilidad con versiones anteriores degradaría el rendimiento del sistema, incluso si no se cargaran módulos heredados.


Más recientemente, los parches de seguridad de Spectre/Meltdown hicieron grandes cambios en lo que debe suceder cuando se cruza el límite del kernel/espacio de usuario. Cualquier módulo compilado antes de que se implementaran las correcciones de Spectre/Meltdown puede no ser confiable con los kernels posteriores a Specre/Meltdown.

Hace solo dos semanas, estaba solucionando un problema de un servidor antiguo que necesitaba un ciclo de encendido manual cuando la automatización aplicaba actualizaciones de seguridad. Esto había sucedido varias veces antes y era reproducible. Descubrí que tenía una versión muy antigua del megasrcontrolador de almacenamiento patentado anterior a los parches de Spectre/Meltdown, que no estaba incluido en las actualizaciones automáticas. Después de actualizar el controlador a la versión actual, el problema desapareció. Por cierto, esto estaba en un sistema RHEL 6.10 simple.

También he visto fallas en los servidores al cargar controladores de monitoreo de hardware propietarios anteriores a Spectre/Meltdown con un kernel posterior a Spectre/Meltdown. Basándome en esta experiencia, estoy totalmente convencido de que las correcciones de Spectre/Meltdown deben tratarse como un evento decisivo: el kernel y los módulos deben ser todas las correcciones anteriores o todas las versiones posteriores; mezclar y combinar solo generará dolor y llamadas de atención a medianoche para el administrador del sistema de guardia.

Y dado que Spectre fue un problema a nivel de diseño de CPU , es "un regalo que sigue dando": algunas personas encontrarán formas novedosas de explotar las debilidades, y luego los desarrolladores del kernel deberán encontrar formas de bloquear las vulnerabilidades.


Estos son solo dos de los grandes problemas que tendría que resolver una API de módulo de kernel heredada compatible con 2.6.0.0. Estoy seguro de que hay muchos otros.


Y luego está el lado más filosófico. Piénselo: ¿qué hace que Linux sea posible?

Una gran parte de esto son especificaciones de hardware abiertas . Si las especificaciones de hardware están abiertas, cualquiera puede participar. Como el código fuente del sistema operativo es abierto, cualquiera puede contribuir, en beneficio de todos. Y no puede mantener las especificaciones de programación de hardware como su secreto comercial si su código de controlador es de código abierto.

Los desarrolladores del kernel de Linux tienden a creer en el modelo de código abierto. Es por eso que han tomado sus decisiones de diseño y desarrollo para que la forma preferida para que el fabricante de hardware participe sea abrir el controlador de código fuente, fusionarlo con la distribución principal del código fuente del kernel y luego (y solo entonces ) Benefíciese de toda la comunidad de desarrolladores del kernel para mantenerlo.

Esto proporciona algún incentivo a los diseñadores y fabricantes de hardware para que esto sea posible. Si tiene algo que desea mantener en secreto, haga el esfuerzo de encapsularlo en un ASIC, o quizás en un firmware firmado si es necesario. (Si hace lo último, conceda a otros el permiso para redistribuir el paquete de firmware).

Pero dado que el kernel es de código abierto, los desarrolladores del kernel no pueden evitar exactamente que otros mantengan los controladores propietarios por separado. Pero tampoco tienen ningún incentivo para preocuparse por ellos.

De hecho, la molestia adicional causada por los controladores binarios propietarios en la depuración del kernel es un incentivo para que el desarrollador del kernel no se preocupe por el desarrollo de controladores propietarios: "Hacen que mi trabajo sea más difícil, ¿por qué debería hacer algo en particular para facilitarles el suyo?"

Entonces, los desarrolladores del kernel generalmente hacen lo que es más ventajoso para ellos como grupo/comunidad. Si eso incluye algún cambio en la API del módulo, que así sea. Los controladores de terceros ni siquiera entran en la ecuación.