Adaptar un dispositivo para que use Ubuntu Touch
Ubuntu Touch es un sistema operativo para teléfonos móviles y tabletas. El proyecto empezó con Canonical y lo continúo el equipo de UBports cuando Canonical lo descontinuó. Hay un detalle importante que se presta a confusión. Puede parecer que, si lleva Ubuntu, se podrá usar en cualquier teléfono o tableta como ocurre en el escritorio. La situación de escritorio y de los dispositivos móviles es diametralmente opuesta. Mientras que en escritorio tenemos un estándar para los diferentes elementos (cosa que permite instalar cualquier sistema operativo sin demasiados problemas), con la arquitectura que se usa en los dispositivos móviles (ARM) la cosa es diferente. La consecuencia es directa: para poder usar Ubuntu Touch en un dispositivo móvil hay que adaptarlo. No tenemos una imagen inicial que funcione en cualquier terminal.
La razón es sencilla. El sistema operativo utiliza drivers para acceder al hardware. Esos drivers están preparados para un sistema operativo concreto (Android) y no se pueden usar directamente para ejecutar otros sistemas operativos. Tampoco es viable hacer ingeniería inversa de los drivers porque es un proceso costoso y nos arriesgamos a una denuncia que paralice todo el trabajo relacionado. En esta entrada veremos en detalle estos elementos así como las formas que hay para superar las limitaciones.
Introducción
El objetivo de esta entrada es acercar un tema complejo a usuarios que posiblemente no tengan cierta formación técnica. Por esta razón he simplificado muchos conceptos para que sean más sencillos de entender. Las definiciones es posible que no sean exactas a nivel técnico pero si ayudarán a llegar a más usuarios.
El problema de los drivers
Los drivers de Android
Un dispositivo móvil es un producto complejo. Contiene un procesador, que gestiona todos los elementos y una serie de módulos que realizan varias tareas. Podemos tener un módulo que se encarga de la pantalla, otro de las comunicaciones e incluso del sistema de carga. Para que el procesador se pueda comunicar con esos elementos necesita saber la forma de hacerlo. No puede decirle directamente al módulo de comunicaciones, “llama a este número de teléfono”. El encargado de traducir una orden al hardware es el driver. El driver recibe la orden y se encarga de coordinar todos los elementos del módulo de comunicaciones para realizar la tarea.
El driver se encarga de la comunicación entre el sistema operativo y el hardware interno. Para que ambos elementos se entiendan tienen que hablar un “idioma” común. Si tenemos un dispositivo con Android, el sistema operativo se comunicará de una forma concreta con el driver. Hay un detalle importante y es que el driver se prepara para una versión específica del sistema operativo (Android en nuestro caso). Eso limita aún más el desarrollo. Más adelante entraremos en detalles.
En un dispositivo móvil el espacio está muy limitado (la mayor parte del espacio libre lo ocupa la batería). Debido a esto, se integran todos los elementos (procesador, modem, etc.) en un único circuito integrado llamado SoC (System on a Chip). Podéis informaros con más detalle en este enlace. Con el fin de facilitar la comprensión de los diferentes elementos, usaré los componentes discretos. Será más sencillo de entender si tenemos en mente los componentes de un ordenador.
Los drivers fuera de Android
Al cambiar el sistema operativo, ya sea Ubuntu Touch, Mobian o Plasma Mobile, cambia ese idioma que se usa. Podemos tener un driver de otro sistema operativo, pero el driver no sabe cómo comunicarse con el procesador. Algunos dispositivos como el PinePhone no tienen ese problema. Los módulos que usan tienen drivers liberados. Ésto implica que se puede modificar el driver para que entienda el idioma de otros sistemas operativos.
Puede parecer que la solución más simple es que todos los usuarios se pasen al PinePhone. Si tiene drivers liberados el desarrollo será mucho más rápido. Este razonamiento es cierto en desarrollos nuevos (Mobian, Posmarket OS, etc.). Con Ubuntu Touch el desarrollo se está alargando un poco. ¿Qué diferencia a Ubuntu Touch de los otros sistemas operativos? La respuesta es la conexión con los drivers de Android (usando una capa llamada Halium). Si esa capa no es necesaria en el PinePhone, hay que quitarla. Lógicamente esto tiene un coste en tiempo y recursos.
La comunidad y la adaptación de Ubuntu Touch
En muchas ocasiones se usa el término de “comunidad” como un ente mágico que consigue programar aplicaciones o adaptar GNU/Linux a cualquier dispositivo que se encienda. La comunidad está formada por muchas personas con diferentes habilidades. Al combinar esas habilidades y dedicar mucho tiempo (que tendrían que estar descansando o con la familia) consiguen esos logros. Hay muchas tareas que se pueden realizar con tiempo: programar aplicaciones, adaptar una distribución, etc. Existen otras tareas que dependen de terceros y que son más complejas de hacer. Una de estas tareas es programar un driver.
Tiempos de desarrollo
Cualquier cosa se puede programar con tiempo y esfuerzo. Para programar un driver necesitas, además, un conocimiento técnico del hardware que tienes entre manos. Si te falta documentación (por ejemplo el fabricante no la ha liberado), llegas a un callejón sin salida. Ésta es la razón de que en las ROMs de terceros de Android haya elementos que no funcionan o que lo hacen de forma inferior al firmware original. En el momento que aparece un fallo de ese tipo necesitas soporte del fabricante del circuito integrado. Ese soporte suele ser exclusivo de los fabricantes OEM (Original Equipment Manufacturer), por lo que queda fuera de la comunidad. La ingeniería inversa exige muchos recursos y en un mercado tan cambiante no es viable. Los fabricantes pueden sacar muchos productos en un año. Si cada producto tiene pequeños cambios a nivel interno, darles soporte se complica.
Esta es la principal razón de que los tiempos de adaptación de un sistema operativo a un dispositivo nuevo sean tan grandes. No importa que tengas un terminal barato o uno que vale 2000 €. La situación es la misma para los dos casos. Por último hay que comentar que los ports se hacen muchas veces con recursos de los propios programadores. Si un programador tiene un dispositivo concreto, trabajará en él. No trabajará en otros modelos porque necesita probar muchas cosas.
Creación de un port con Halium
Para adaptar Ubuntu Touch a un nuevo dispositivo necesitamos trabajar con Halium. La única excepción a esta regla la tenemos en dispositivos como el PinePhone / PineTab que tienen drivers liberados. El resto de terminales que vienen de serie con Android tienen que pasar por Halium. Halium se encarga de unificar la capa de abstracción de hardware (HAL). Tiene una parte común con GNU/Linux que funciona igual en todos los dispositivos y una parte propia que depende del hardware que tenga cada equipo. Halium no se encarga de elementos de más alto nivel como la pantalla, el interfaz de usuario o las aplicaciones. En cierta medida, sería como si Halium fuera una distribución de GNU/Linux que trabaja en modo consola. Se comunica con el hardware pero sólo hace el trabajo de bajo nivel. Por encima puede tener Ubuntu Touch, Debian o cualquier otra distribución.
Requisitos de Halium
Halium puede funcionar con trabajo en cualquier dispositivo siempre que cumpla unos requisitos mínimos. El primer elemento es el código fuente del Kernel. El kernel está formado por una serie de archivos que contienen instrucciones. Esas instrucciones son las que permitirán acceder al hardware. Hemos visto antes que el driver se encarga de esta tarea, entonces, ¿para qué necesitamos el kernel?. El kernel incluye un sistema mínimo que hace la comunicación entre los diferentes elementos de una tarjeta de circuito impreso (PCB). Por ejemplo, si tenemos un módulo que se comunica con el procesador con el bus I2C, no tenemos que implementarlo nosotros. Ya está todo incluido en el código fuente.
Una PCB contiene los diferentes circuitos integrados y las conexiones entre ellos. En diseños más complejos las conexiones (pistas) pueden ir por dentro de la tarjeta. Estructuralmente es un sándwich formado por diferentes capas. El bus I2C es un bus de comunicaciones que se usa en electrónica. Permite controlar diferentes periféricos como sensores externos.
Después del kernel, los siguientes requisitos para usar Halium son la memoria RAM y el espacio de almacenamiento. Halium está pensado para teléfonos y tabletas. Estos equipos tienen recursos limitados y se pueden encontrar terminales con 1 GB de RAM o 16 GB de memoria interna. Ambos valores son los mínimos que se recomiendan antes de empezar a trabajar. Si tenemos un dispositivo con menos recursos, no es aconsejable usarlo ya que dará muchos problemas y la experiencia de usuario será mala.
Pasos a seguir si queremos trabajar con Halium
Si cumplimos los requisitos el siguiente paso es preparar las herramientas de desarrollo. No voy a entrar en esta entrada para explicar los siguientes pasos. En el caso de estar interesados en trabajar con Halium podéis pedir más información de varias formas:
- IRC: #halium on Freenode
- Matrix: #halium:matrix.org
- Telegram: @halium
Los plazos para tener una versión de Halium funcional pueden ser largos. Es complicado decir, en 200 horas de trabajo estará todo funcionando. Las cosas tienen su tiempo y recordad que los programadores trabajan en su tiempo libre sin recibir ingresos de ningún tipo.
GSI (Imágenes genéricas de Android)
Éstos problemas que hemos visto aparecen también en Android. Google libera una versión de Android (con un par de cambios menores) y los fabricantes empiezan una carrera para actualizar sus terminales antes que la competencia. El proceso es costoso en tiempo aunque tengas los recursos necesarios y al final provoca que en el mercado haya una gran variedad de versiones de Android. Con la finalidad de reducir los tiempos tenemos las imágenes genéricas de Android (GSI). De forma simplificada, el sistema tiene varias particiones. Por encima se ejecuta una imagen genérica que contiene todos los elementos de Android y esa parte se comunica con un hardware que es específico de cada dispositivo. En la partición se encuentran los drivers y no están acoplados con el sistema operativo.
Al separar por una parte el sistema operativo con una imagen genérica de los drivers, se reducen mucho los costes. Permite que Google libere una versión nueva de Android y que esa versión utilice los drivers que vienen de serie en el dispositivo. Si sustituimos la imagen genérica de Google por una que contenga Ubuntu Touch o Debian podemos conseguir que el dispositivo sea funcional usando muchos menos recursos. Lógicamente la cosa no es tan simple en la realidad, pero ayuda en la tarea de realizar una adaptación a un nuevo dispositivo.
El interfaz de usuario
Hasta ahora hemos visto la parte de bajo nivel. Tenemos un dispositivo y conseguimos que se inicie con GNU/Linux. Halium se encarga del control del hardware usando los drivers de Android. El siguiente paso es conectar esta parte con el interfaz de usuario. Ubuntu Touch usa Lomiri, un escritorio que toma como base Unity. Desde Lomiri podemos usar tanto aplicaciones nativas como aplicaciones de escritorio dentro de un contenedor llamado Libertine.
Supongamos que queremos usar la aplicación de la cámara. Al pulsar en la pantalla se abrirá la aplicación y se comunicará con el driver que gestiona la cámara. En muchas ocasiones pueden aparecer complicaciones en esta parte. Por ejemplo, podemos hacer una foto y que el procesado de la fotografía dure mucho tiempo. No es una tarea que realice directamente el driver y es necesario dedicar tiempo a depurar el problema antes de poder aplicar una solución. Con esto quiero decir que en este punto aún queda trabajo por hacer. Poco a poco se van corrigiendo los diferentes detalles pero no es 100 % funcional. Un sistema operativo es complejo y tiene muchos elementos que interactúan entre sí. Lo divertido es que puedes arreglar una cosa en un sitio y provocar al mismo tiempo un problema en otra parte.
Si necesitamos un terminal que funcione siempre hay que ir a otros sistemas operativos como Android / iOS. Las cosas suelen funcionar, aunque en algunas ocasiones aparecen bugs que tardan meses en resolverse (si lo hacen). La diferencia entre esos sistemas operativos y otros como Ubuntu Touch es el objetivo final. Android / iOS tienen como objetivo vender terminales mientras que la comunidad tiene como objetivo dar soporte a equipos actuales que siguen funcionando. El coste está claro: se tienen menos recursos y los proyectos avanzan más despacio.
Conclusiones
En esta entrada hemos visto las tareas que hay que realizar para adaptar un sistema operativo, como Ubuntu Touch, a un dispositivo nuevo. En el mercado móvil no existe el mismo estándar que hay en el escritorio y tenemos más diseños a medida. Estos diseños a medida provocan que los tiempos de adaptación de un sistema operativo sean grandes (suponiendo que se pueda). Si no somos programadores, la forma de ayudar es participando en las pruebas que hacen los diferentes grupos. Por ejemplo, si se está terminando una adaptación y tenemos el terminal, podemos probarlo y reportar los errores que encontremos. Lógicamente habrá fallos y es posible que no funcione todo. Debido a esto es aconsejable hacer las pruebas en un teléfono secundario.
Personalmente tengo la sensación de que se están dedicando muchos esfuerzos a realizar adaptaciones (ports) y pocos esfuerzos a programar aplicaciones. Podemos tener muchos dispositivos y usuarios con Ubuntu Touch, pero faltan aplicaciones. Una aplicación Web, por ejemplo la de Deezer puede reproducir música, pero no se adapta al teléfono. Si modificamos el volumen con los botones físicos no se modifica el volumen de multimedia sino el volumen general. El resultado es que la experiencia del usuario es menor. Entiendo que es complicado programar aplicaciones pero hay que hacerlo poco a poco. Las primeras aplicaciones serán más sencillas y con el tiempo veremos mejores aplicaciones. La experiencia al programar se nota mucho.
También se pueden escribir pequeñas entradas en blogs. No importa que sean cortas. Lo interesante es que Google las indexe y de esa forma mejore la percepción de Ubuntu Touch en otros ámbitos. Si os interesan este tipo de entradas lo podéis indicar en los comentarios. No hace falta registrarse. Puede pasar un poco hasta que se publiquen los comentarios ya que tenga que moderarlos. Es la única forma de evitar el spam en la Web.
¿Os animáis a participar en la comunidad?
Referencias
- Proyecto Halium.
- Documentación de desarrollo del proyecto Halium.
- Adaptación de Halium y UBports.
- Sistema operativo Mobian.
- Sistema operativo Postmarket OS.
Agradecimientos
Esta entrada era inicialmente más sencilla pero se ha extendido un poco. Quiero agradecer la revisión que han hecho Josu (@j2g2rp), Milan (@milkor73) y Pietre (@PietreUX).
Muy bien explicado se necesiatn mas de estas explicaciones en español, todo mi apoyo a Ubuntu touch y a al canal de telegram t.me/UBPorts_ES
Gracias por el comentario Pietre.
Me está sorprendiendo el número de visitas que está recibiendo esta entrada. Aunque es bastante técnica, creo que se entienden los conceptos bien. Si después hay alguna duda que no queda explicada, siempre puedo ampliar la entrada.
Un saludo.