Biónico (software)

Biblioteca estándar C para el sistema operativo Android

Bionic es una implementación de la biblioteca estándar C , desarrollada por Google para su sistema operativo Android . Se diferencia de la biblioteca C de GNU (glibc) en que está diseñada para dispositivos con menos memoria y potencia de procesador que un sistema Linux típico . Es una combinación de código nuevo y código de FreeBSD , NetBSD y OpenBSD publicado bajo una licencia BSD , en lugar de glibc, que utiliza la licencia pública general reducida de GNU . Esta diferencia fue importante en los primeros días de Android, cuando los enlaces estáticos eran comunes, y dado que Bionic tiene su propia interfaz binaria de aplicación , no se puede reemplazar por una libc diferente sin romper todas las aplicaciones existentes.

Bionic es una biblioteca C para usar con el núcleo Linux y proporciona libc , libdl y libm ( la funcionalidad libpthread es parte de libc , no una biblioteca separada como en otros sistemas). Esto difiere de las bibliotecas C BSD con las que Bionic comparte código, porque requieren un núcleo BSD .

Objetivos originales

Los objetivos originales declarados públicamente para Bionic fueron los siguientes: [1] [2]

  • Con licencia BSD : Google quería aislar las aplicaciones de Android del efecto de las licencias copyleft para crear un espacio de usuario y un ecosistema de aplicaciones propietarios , [3] pero:
    • Android se basa en el kernel Linux, que está sujeto a la licencia pública general GNU (GPL) versión 2.
    • La biblioteca C estándar más extendida para el núcleo Linux es la biblioteca C de GNU (glibc), que está sujeta a la licencia pública general reducida de GNU (LGPL), también una licencia copyleft. A diferencia de la GPL, la LGPL permite explícitamente la vinculación dinámica, pero no permite la vinculación estática de software propietario sin proporcionar el código fuente o archivos objeto enlazables.
    • La licencia BSD permisiva es una licencia sin copyleft que es compatible en ambas direcciones. Un sustituto de glibc con licencia BSD podría actuar como una capa de aislamiento entre el núcleo copyleft (kernel) y las aplicaciones sin copyleft, y por eso fue elegida por Google para su Bionic como sustituto de glibc. [4]
  • Tamaño pequeño: Bionic era mucho más pequeño que la biblioteca GNU C; lo que es más importante, sus requisitos de memoria eran (y siguen siendo) mucho menores.
  • Velocidad: Bionic fue diseñado para CPU con frecuencias de reloj relativamente bajas.

Arquitecturas soportadas

Bionic solo es compatible con kernels Linux, pero actualmente es compatible con las arquitecturas arm, arm64, riscv64, x86 y x86-64. La plataforma en sí requirió armv7 con Neon desde Marshmallow , [5] aunque el Android Native Development Kit (NDK) continuó admitiendo armv5 (al que llamó armeabi) hasta NDK r16. El NDK todavía es compatible con armv7, aunque NDK r24 eliminó el soporte para no Neon. Históricamente, había soporte parcial para SH-4 en la plataforma, pero nunca se enviaron dispositivos y el soporte se eliminó desde entonces. El NDK nunca admitió SH-4, y el soporte para MIPS y MIPS64 se eliminó del NDK en r17.

Componentes

Algunas partes del código fuente de libc, como stdio , provienen de BSD (principalmente OpenBSD ), mientras que otras, como la implementación de pthread , se escribieron desde cero.

La implementación del asignador de memoria dinámica ha cambiado con el tiempo. Antes de Lollipop había un único asignador de memoria nativo, dlmalloc de Doug Lea . Para Lollipop y Marshmallow había dos implementaciones: dlmalloc y jemalloc . jemalloc ofrece un rendimiento mucho mayor que dlmalloc, pero a costa de la memoria adicional necesaria para la contabilidad. La mayoría de los dispositivos usaban jemalloc, pero los dispositivos con poca memoria todavía usaban dlmalloc. Para Nougat hasta Android 10 , todos los dispositivos usan jemalloc. Los dispositivos con poca memoria usan una configuración "esbelta" de jemalloc que deshabilita el tcache para casi igualar la sobrecarga de memoria más baja de dlmalloc mientras mantiene la mayor parte de la velocidad de jemalloc. En Android 11 , el asignador de memoria para la mayoría de los dispositivos se cambió a Scudo, que sacrifica parte del alto rendimiento de jemalloc por funciones adicionales de refuerzo de la seguridad. [6] Sin embargo, los dispositivos con poca memoria aún pueden usar jemalloc. [7]

Algunos dispositivos de 64 bits, como el Nexus 9 , son efectivamente dispositivos con poca memoria debido a los requisitos de espacio adicional de los punteros de 64 bits y el alojamiento de dos cigotos. ( Zygote es un servicio del sistema Android que es el padre de todos los procesos de aplicación de Android. [8] )

El código fuente de libm es en gran parte de FreeBSD , pero con un ensamblador optimizado aportado por varios proveedores de SoC .

El enlazador dinámico (y libdl) se escribieron desde cero.

Bionic no incluye libthread_db (usado por gdbserver ), pero el NDK sí. La plataforma Android incluía un gdbserver vinculado estáticamente, de modo que los desarrolladores pueden usar la última versión de gdb incluso en dispositivos antiguos. Dado que Android abandonó la compatibilidad con gdb y cambió a lldb, esto ya no es relevante.

En Android no hay libpthread, libresolv ni librt independientes: toda la funcionalidad está en libc. En el caso de libpthread, no se intenta optimizar para el caso de un solo subproceso, ya que las aplicaciones se encuentran en un entorno de múltiples subprocesos incluso antes de que se ejecute la primera instrucción del código de terceros.

La plataforma Android utiliza libc++ para la biblioteca estándar de C++ (las versiones hasta Lollipop inclusive usaban stlport). El NDK ofrecía históricamente stlport y GNU libstdc++, pero estos fueron eliminados a partir del NDK r18. [9] Tenga en cuenta que si algún código nativo en una aplicación de Android usa C++, todo el C++ debe usar el mismo STL . El sistema operativo Android no proporciona el STL y debe incluirse con cada aplicación.

Diferencias con POSIX

Aunque Bionic tiene como objetivo implementar todo C11 y POSIX , todavía faltan (a partir de Oreo) alrededor de 70 funciones POSIX [10] en libc. También hay funciones POSIX como la familia endpwent/getpwent/setpwent que no son aplicables a Android porque carece de una base de datos passwd . A partir de Oreo , libm está completo.

Algunas funciones no se ajustan deliberadamente a los estándares POSIX o C por razones de seguridad, como printf , que no admite la %ncadena de formato. [11]

Muchas de las extensiones GNU más utilizadas están implementadas en Bionic, al igual que varias extensiones BSD.

Relación con el NDK

El código de la plataforma utiliza Bionic directamente, pero los desarrolladores externos utilizan el kit de desarrollo nativo de Android (NDK). Muchos desarrolladores externos aún utilizan versiones anteriores del sistema operativo, lo que contribuye a la creencia generalizada de que a Bionic le faltan muchas funciones. Gingerbread exportó 803 funciones desde libc, pero Oreo exporta 1278 (un aumento de 1,6x). [10]

Históricamente, el NDK y la plataforma divergieron, pero NDK r11 y posteriores reemplazaron las bifurcaciones del NDK con sus equivalentes de plataforma actuales. Este trabajo se centró inicialmente en los compiladores GCC y Clang .

Antes de NDK r14, cuando se ofrecieron por primera vez encabezados "unificados" de forma opcional, el NDK tenía copias bifurcadas de los encabezados de la plataforma para diferentes niveles de API. Esto significaba que las correcciones solo de encabezados (correcciones a definiciones de constantes o estructuras, por ejemplo) no estaban disponibles para la mayoría de los usuarios de NDK porque apuntaban a un nivel de API anterior, pero las correcciones de la plataforma solo se aplicaban a los encabezados de la plataforma actuales. En el período de desarrollo de Oreo, los encabezados de la plataforma se anotaron con información de nivel de API para que se pueda usar el mismo conjunto de encabezados para todos los niveles de API, y solo sean visibles las funciones disponibles en el nivel de API de destino del desarrollador. Estos son los encabezados denominados "unificados" y han sido los predeterminados desde NDK r15.

Antes de NDK r16, el NDK vinculaba una biblioteca llamada libandroid_support.a al código que usaba libc++ para proporcionar funciones requeridas por libc++ que no estaban en versiones anteriores del sistema operativo. Este no era el mismo código que usaba la plataforma e introducía numerosos errores (como la interrupción de los argumentos posicionales de la familia printf en cualquier código que usara libc++). Desde NDK r16 hasta r25, libandroid_support.a todavía existía, pero se creaba directamente a partir de la fuente de la plataforma vigente en ese momento en el momento en que se creaba cada NDK. Desde NDK r26, libandroid_support.a ya no existe, porque todas las versiones del sistema operativo que aún son compatibles con el NDK contienen todo lo que necesita libc++.

Fortalecer la fuente

A partir de Android Jelly Bean MR1 (4.2), Bionic admite una funcionalidad similar a la de glibc _FORTIFY_SOURCE, [12] que es una característica en la que las funciones de memoria y cadenas no seguras (como strcpy(), strcat(), y memcpy()) incluyen comprobaciones de desbordamientos de búfer. Estas comprobaciones se realizan en tiempo de compilación si los tamaños de búfer se pueden determinar en tiempo de compilación, o en tiempo de ejecución en caso contrario. Debido a que fortify depende del soporte en tiempo de ejecución de libc, su portabilidad a versiones anteriores de Android es limitada. [13] La plataforma en sí está construida con _FORTIFY_SOURCEenabled.

Históricamente, una de las deficiencias de fortify ha sido que está estrechamente vinculado con GCC, lo que hace que sea muy difícil brindar un buen soporte en otros compiladores, como Clang. Esto significó que cuando Android cambió a Clang como su compilador predeterminado, [14] la implementación de fortify de Bionic se volvió sustancialmente menos útil. En Android Oreo (8.0), fortify de Bionic fue revisado [15] teniendo en cuenta a Clang, lo que resultó en que fortify en Clang brindara una experiencia a la par de fortify en GCC. Desde esta revisión, se agregaron algunas verificaciones además de las de glibc para detectar código que, si bien no necesariamente causa un comportamiento indefinido, es obviamente incorrecto. Debido a que esta nueva implementación no requiere más soporte de libc que la anterior, las mejoras específicas de Clang están disponibles para aplicaciones destinadas a versiones de Android anteriores a Oreo.

Controversias

Para la creación de Bionic, Google utilizó archivos de encabezado del núcleo de Linux con licencia GPLv2 . Para deshacerse de la GPL, Google afirmó que limpió los archivos de encabezado de cualquier obra susceptible de copyright, reduciéndolos a "hechos" no sujetos a copyright. [16] [17] El creador de Linux, Linus Torvalds, consideró que la conducta de Google era aceptable, [17] pero la interpretación de Google de la GPL ha sido cuestionada, por ejemplo por Raymond Nimmer, un profesor de derecho en el Centro de Derecho de la Universidad de Houston . [18]

Véase también

Referencias

  1. ^ Burnette, Ed (4 de junio de 2008). "Patrick Brady analiza Android". ZDNet .
  2. ^ Turner, David (7 de febrero de 2009). "Preguntas sobre Bionic". El nombre "Bionic" proviene del hecho de que es en parte BSD y en parte Linux: su código fuente consiste en una mezcla de fragmentos de la biblioteca C de BSD con fragmentos específicos de Linux personalizados que se utilizan para manejar subprocesos, procesos, señales y algunas otras cosas.
  3. ^ Anatomía y fisiología de Android (PDF) , pág. 36, archivado desde el original (PDF) el 8 de abril de 2016 , consultado el 15 de julio de 2017 , Licencia: queremos mantener la GPL fuera del espacio de usuario
  4. ^ Florian Mueller. "Patentes de software libre".
  5. ^ "Definición de compatibilidad con Android 6.0".
  6. ^ "Fortalecimiento del sistema en Android 11". Blog de desarrolladores de Android . Consultado el 20 de diciembre de 2020 .
  7. ^ "Scudo". Proyecto de código abierto de Android . Consultado el 20 de diciembre de 2020 .
  8. ^ "Zigoto". Anatomía de Android . Archivado desde el original el 15 de marzo de 2016. Consultado el 14 de marzo de 2016 .
  9. ^ "Historial de revisiones del NDK | Android NDK".
  10. ^ ab "Estado biónico de Android".
  11. ^ Elliott Hughes. "libc: #define para eliminar el soporte para %n de printf(3)?".
  12. ^ "Notas de la versión de Android 4.2 Jelly Bean". Desarrolladores de Android . android.com . Consultado el 27 de diciembre de 2013 .
  13. ^ "Android 4.2 y FORTIFY_SOURCE". Discusiones sobre seguridad de Android . Consultado el 27 de diciembre de 2013 .
  14. ^ "Registro de cambios de Android NDK". Android NDK . android.googlesource.com . Consultado el 28 de agosto de 2017 .
  15. ^ "FORTIFY en Android". Blog de desarrolladores de Android . android-developers.googleblog.com . Consultado el 28 de agosto de 2017 .
  16. ^ Google Android y los encabezados de Linux en theregister.com (2011)
  17. ^ ab Android: demandado por Microsoft, no por Linux Archivado el 13 de enero de 2016 en Wayback Machine "Microsoft lanza una nueva demanda contra Android, la opinión de Linus Torvalds sobre los encabezados del kernel de Linux y Android" en ITworld (21 de marzo de 2011)
  18. ^ Riesgo de infracción y divulgación en el desarrollo de plataformas copyleft en ipinfoblog.com por Raymond Nimmer (2011)
  • Google I/O 2008: Anatomía y fisiología de un Android en YouTube
  • Página de inicio para desarrolladores de Android
  • Página de inicio del kit de desarrollo nativo de Android (NDK)
  • Fuentes biónicas (repositorio oficial)
  • Notas biónicas en eLinux.org
Obtenido de "https://es.wikipedia.org/w/index.php?title=Bionic_(software)&oldid=1242017782"