Ubuntu en Android

De GiLUG
La revisió el 17:28, 11 abr 2017 per Narcisgarcia (discussió | contribucions) (Update SL4A link)
Salta a: navegació, cerca

Català - Castellano - English


Introducción: Esta es una guia para hacer funcionar un contenedor de Ubuntu GNU/Linux dentro de una sesión del sistema operativo Android, y así tener la funcionalidad de un ordenador de escritorio sin perder rendimiento. Es una guia muy detallada, que sirve para Debian y derivados, tambien útil para quien quiera crear un asistente o mejorar el procedimiento.

Notas:

  • En el momento de escribir esta guía (noviembre del 2011), Canonical todavía no tenía lista su anunciada solución, però des del 2014 siguen la estrategia de Cyanogenmod y con más éxito. La versión con que el escritorio predeterminado (Unity) funciona mejor es la 12.04 (Precise)
  • El total de descargas que se propone puede llegar a 1GiB de datos; si las hace todas desde el aparato tome en cuenta la tarifa de datos que le aplica el proveedor de acceso a internet.
  • Se ha explorado la posibilidad de utilizar un contenedor LXC para tener un contenedor completamente normal, pero no ha funcionado por el uso que hace Android de bionic lic en lugar de GNU libc.

Permisos de superusuario (root)

Es un requisito tener acceso "su" para administrar el sistema operativo. Puede ver la guia Abrir permisos en Android

Acceso por terminal

Terminal local

Siempre es recomendable tener una aplicación de Terminal (que se puede obtener libremente con F-Droid) disponible para poder hacer gestiones con movilidad, pero las preparaciones largas y complejas es más comodo hacerlas desde un ordenador de escritorio controlando el aparato conectado por USB.

Control remoto

En la distribución Ubuntu GNU/Linux, a partir de la versión 12.10 en el repositorio universal hay disponible el paquete android-tools-adb que permite el control remoto a un aparato con Android en modo de depuración USB. Tambien hay un repositorio independiente que proporciona android-tools para anteriores versiones.

Para utilizar el Android Debug Bridge (ADB) debe tener el aparato en marcha, conectado por USB, y con el modo de «Depuración USB» habilitado en las opciones del desarrollador (developer) de Android.

ADB por USB
  • Para comprobar la conectividad:
adb devices

(debe mostrar una «lista» con un identificador raro que diga que es un dispositivo; device)

  • Para abrir una sesión de terminal en el aparato:
adb shell
  • Para iniciar una sesión como superusuario (root), y tener permisos de administración de Android:
su
  • Para finalizar como superusuario y después tambien cerrar la sesión de terminal:
exit
exit
ADB por red

Muchas conexiones por USB son poco estables (se cortan muy a menudo y te das cuenta de que escribes en tu ordenador), y en estos casos se resuelve por red (Wifi). Cuando se hace esto es importante que el aparato no tenga conesión directa a internet (por ejemplo con el operador telefónico) y se trate de una comunicación por el Wifi local.

  • Desde Android, para ver los dispositivos de red que tiene activados (default... dev -->):
ip route list
  • Desde Android, para ver la dirección IP de un dispositivo de red (por ejemplo wlan0):
ifconfig wlan0
  • Para establecer desde el ordenador que la comunicación será via red (por ejemplo a la IP 192.168.1.122):
adb connect 192.168.1.122
  • Para abrir una sesión de terminal en el aparato:
adb shell
  • Para iniciar una sesión como superusuario (root) y tener permisos de administración de Android:
su
  • Para finalizar como superusuario y tambien cerrar la sesión de terminal:
exit
exit
Notas adicionales
  • En esta guia, en donde se indican instrucciones escritas es para ejecutar en una ventana de terminal local o remoto.
  • Si obtiene mensajes de tipo «Operation not permitted» suele ser porque no ha iniciado como superusuario (su)

Comprobar las herramientas disponibles

En un terminal compruebe esta instrucción:

chroot

Le puede decir dos cosas: o bien la presentación de ayuda (con «usage: chroot...») o bien el mensahe de error «chroot: not found». En este último caso (not found) tiene una variante de Android muy recortada, y necesita reemplazarla por otra más libre como CyanogenMod o Replicant. Otras alternativas más técnicas son: Superponer directorios sobre Android o Formatear una targeta de memoria.

Anotar la arquitectura

Se puede mirar qué generación de procesador utiliza Android con una de las siguientes instrucciones:

uname -m
cat /proc/cpuinfo

Si el procesador ARM del aparato soporta coma flotante (ARMv7 o superior, por ejemplo armv7l seria el caso), entonces se pueden utilizar paquetes «armhf» en lugar de «armel». Esto mejora la velocidad de algunos procesos.

Preparar el espacio

Para que funcionen los enlaces y accesos a dispositivo hace falta que el nuevo contenedor esté en una partición apropiada para GNU/Linux, como por ejemplo Ext3 o Ext4. Con la instrucción mount se puede ver el formato de cada volumen, y con esta sintaxis se ve muy claro:

mount | cut -f 1-5 -d ' ' | sed -e 's/ on / /g' | sed -e 's/ type / /g' | cut -f 2-3 -d ' '

Y se puede filtrar para ver sólo lo que nos interesa:

mount | cut -f 1-5 -d ' ' | sed -e 's/ on / /g' | sed -e 's/ type / /g' | cut -f 2-3 -d ' ' | sed -e '/ext.$/!d'

Una vez vistas las rutas compatibles, debe valorar el espacio libre que hay con esta instrucción:

df

Si en el espacio libre (Free) no se menciona la unidad de medida (100K, 100M, 100G), significa que se expresa en K (KiB). A tener en cuenta tambien que la ruta /cache funciona «como una papelera interna» y que su contenido puede ser borrado automáticamente.

Necesita almenos 100MiB para una instalación elemental (core solo), o hacia los 250MiB para un debootstrap, pero se puede llegar a utilizar 2 o 3GiB si instala todas las grandes aplicaciones de escritorio de uso común, aparte de contar con un poco de espacio de trabajo. Igualmente se pueden hacer instalaciones «para todos los bolsillos».

Para el resto de guía supondremos que ha escogido la partición /data , y entonces el nuevo sistema operativo lo pone en /data/ubuntu . Debe habilitar entonces los permisos de escritura, ejecución, dispositivos y superusuario en la partición, y crear el subdirectorio::

mount -o remount,rw,dev,exec,suid,noatime /data
PuntoRaiz="/data/ubuntu"
mkdir "$PuntoRaiz"
cd "$PuntoRaiz"

Obtener una base de sistema operativo

Esta sería la manera de construirlo desde otro ordenador (suponiendo arquitectura para armhf) en una partición Ext2/Ext3:

sudo debootstrap --verbose --arch=armhf --foreign precise precise-armhf
  • Para transportar el arbol de directorios de un dispositivo a otro, hay que copiarlo con permisos de superusuario, para que los atributos y propietarios de ficheros y directorios no se pierdan por el camino. Para abrir así un explorador de carpetas con Ubuntu, se puede ejecutar (Alt+F2) «gksudo nautilus».

Pero aqui tambien proponemos la manera de hacerlo completamente desde el aparato con Android: descargando una base preparada (del web oficial) con sólo una de estas instrucciones, según la versión y variante que necesite (se publican más versiones en cdimage.ubuntu.com):

wget http://cdimage.ubuntu.com/ubuntu-core/releases/precise/release/ubuntu-core-12.04.2-core-armhf.tar.gz
wget http://cdimage.ubuntu.com/ubuntu-core/releases/oneiric/release/ubuntu-core-11.10-core-armel.tar.gz
wget http://cdimage.ubuntu.com/ubuntu-core/releases/quantal/release/ubuntu-core-12.10-core-armhf.tar.gz
wget http://cdimage.ubuntu.com/releases/precise/release/ubuntu-12.04-preinstalled-desktop-armhf+ac100.tar.gz
wget http://cdimage.ubuntu.com/releases/oneiric/release/ubuntu-11.10-preinstalled-desktop-armel+ac100.tar.gz

Nota: Las «preinstaled» traen todo el software de una instalación típica, pero tambien elementos que hay que limpiar para arrancar el contenedor.

Con el fichero descargado, toca desempaquetarlo:

tar -xzf ubuntu-core-12.04.2-core-armhf.tar.gz
rm ubuntu-core-12.04.2-core-armhf.tar.gz

Adaptar la base

Corrija algunos enlaces dentro del directorio de la base, para adecuarlos más a la situación:

chmod 755 "$PuntoRaiz"
if [ -d /acct ] ; then mkdir -p acct ; fi
cd var
if [ -L run ] ; then rm run ; ln -s ../run run ; fi
if [ -L lock ] ; then rm lock ; ln -s ../run/lock lock ; fi
cd "$PuntoRaiz"

Limpie directorios que a veces vienen con contenido para una instalación nativa:

if [ -d proc ] ; then rm -R proc/* ; fi
if [ -d dev ] ; then rm -R dev/* ; fi
if [ -d sys ] ; then rm -R sys/* ; fi
if [ -d var/run/dbus ] ; then rm -R var/run/dbus/* ; fi

Montar recursos de Android

mount -o bind "/proc" "$PuntoRaiz/proc"
mount -o bind "/dev" "$PuntoRaiz/dev"
mount -o bind "/dev/pts" "$PuntoRaiz/dev/pts"
mount -o bind "/sys" "$PuntoRaiz/sys"
if [ -d /acct ] ; then mount -o bind "/acct" "$PuntoRaiz/acct" ; fi
if [ -d /dev/cpuctl ] ; then mount -o bind "/dev/cpuctl" "$PuntoRaiz/dev/cpuctl" ; fi

Si quiere hacer disponibles las carpetas de Android, se debe que mirar qué particiones hay montadas. Se puede hacer con un simple mount o con esta instrucción que simplifica la información:

mount | sed -e '/ \/mnt\//!d' | sed -e '/^\//!d' | cut -f 2,3 -d ' ' | cut -f 2- -d '/' | cut -f 1 -d ' ' | sed -e 's/^/\//g'

Si por ejemplo queremos montar /mnt/sdcard hacemos:

mkdir -p "$PuntoRaiz/mnt/sdcard"
mount -o bind "/mnt/sdcard" "$PuntoRaiz/mnt/sdcard"

Entrar en el nuevo sistema y establecer servicios elementales

Desde la incorporación del sistema de inicio de servicios Upstart, los contenedores Chroot no inician los servicios como una instalación normal, y hay que hacerlo manualmente.

chroot "$PuntoRaiz" /bin/su
mount -a

Asegúrese de que figure alguna cosa montada, para que no fallen algunas utilidades:

if [ "$(mount)" = "" ] ; then mount -o bind /selinux /selinux ; fi

Complete el debootstrap si es el caso, en la misma arquitectura:

if [ -x /debootstrap/debootstrap ] ; then /debootstrap/debootstrap --second-stage ; fi

Parche para evitar error de inicio de servicios Upstart:

dpkg-divert --local --rename --add /sbin/initctl
ln -s /bin/true /sbin/initctl

Configure la red:

echo "nameserver 4.2.2.2" > /etc/resolv.conf
echo "nameserver 8.8.8.8" >> /etc/resolv.conf
echo "nameserver 8.8.4.4" >> /etc/resolv.conf
echo "127.0.0.1 localhost" > /etc/hosts

Compruebe si hay repositorios establecidos:

cat /etc/apt/sources.list

Si no había nada, o los «universe» estan deshabilitados con #, escribalos con las siguientes instrucciones (ejemplo para Ubuntu 12.04, llamado «precise»):

Version="precise"
echo "deb http://ports.ubuntu.com/ ${Version} main universe" > /etc/apt/sources.list
echo "# deb-src http://ports.ubuntu.com/ ${Version} main universe" >> /etc/apt/sources.list
echo "" >> /etc/apt/sources.list
echo "deb http://ports.ubuntu.com/ ${Version}-updates main universe" >> /etc/apt/sources.list
echo "# deb-src http://ports.ubuntu.com/ ${Version}-updates main universe" >> /etc/apt/sources.list
echo "" >> /etc/apt/sources.list
echo "deb http://ports.ubuntu.com/ ${Version}-security main universe" >> /etc/apt/sources.list
echo "# deb-src http://ports.ubuntu.com/ ${Version}-security main universe" >> /etc/apt/sources.list
apt-get update

Instale servicios y herramientas para evitar quejas (los paquetes -es son para el idioma castellano):

Nota: si aparece algún recuadro de pregunta o mensaje, se cambia de opción con el TABulador, y se pulsan los botones con el espacio, lo cual es fácil de hacer si se está trabajando con ADB desde un ordenador.
apt-get install dbus dbus-x11
mkdir -p /var/run/dbus
apt-get install language-pack-es
update-locale
IdiomaPredeterminado="es_ES.UTF-8"
export LANG="$IdiomaPredeterminado"
export LANGUAGE="$IdiomaPredeterminado"
echo "LANG=\"$IdiomaPredeterminado\"" >> /etc/default/locale
echo "LANGUAGE=\"$IdiomaPredeterminado\"" >> /etc/default/locale

Inicie el servicio DBus del cual dependen muchas aplicaciones (no se puede aprovechar el de Android):

DbusPid="$(dbus-daemon --system --print-pid --fork)"

Instale la parte básica de Ubuntu y aplique actualizaciones. Este proceso tarda bastante:

apt-get install ubuntu-minimal ubuntu-standard
apt-get upgrade

Instale escritorio y aplicaciones que le interese. Este proceso puede tardar MUCHO:

apt-get install sudo ubuntu-desktop libreoffice libreoffice-l10n-es language-pack-gnome-es

(si aparece un recuadro de mensaje o pregunta, se desplaza con el TABulador, y se pulsa con el espacio).

Abrir una cuenta de usuario normal

Utilizando el escritorio y aplicaciones como usuario normal (no root) mejora la seguridad y la admisión por parte de algunos elementos que lo requieren.

cp -a /etc/adduser.conf /etc/adduser.conf.bak
cat /etc/adduser.conf.bak | sed -e 's/^#EXTRA_GROUPS=/EXTRA_GROUPS=/g' > /etc/adduser.conf
NombreUsuaria=usuario
adduser --add_extra_groups --gecos "" $NombreUsuaria

Incluir la nueva cuenta ($NombreUsuaria) en el grupo común de usuarios y grupos de administración que haya:

usermod --append --groups users $NombreUsuaria
usermod --append --groups sudo $NombreUsuaria
usermod --append --groups adm $NombreUsuaria
usermod --append --groups admin $NombreUsuaria

Crear un grupo especial en donde incluir el usuario, para que pueda abrir puertos de entrada

addgroup --gid 3003 sockets
usermod --append --groups sockets $NombreUsuaria

Habilitar interfaz gráfica

Aunque ya ha aparecido alguna herramienta X-Server para utilizar aplicaciones en pantalla directamente sin control remoto, de momento exponemos el método tradicional 2011-2012 (suponiendo como ejemplo que la pantalla del aparato tiene una resolución de 1280x720):

apt-get install xvfb x11vnc xtightvncviewer
if [ "$Copyrect" = "" ] ; then CrOptions="-nowirecopyrect -noscrollcopyrect" ; else CrOptions="-ncache" ; fi
MoreOptions="-create -localhost -xrandr $CrOptions -rfbport 5900 -nopw -forever -permitfiletransfer -nevershared -scale 1/1"
echo "x11vnc $MoreOptions -env FD_GEOM=${1:-1280x720x16} -afteraccept 'x-session-manager &' -logfile '.x11vnc.log'" > /tmp/xvnc.sh
chmod a+rx /tmp/xvnc.sh
su -l $NombreUsuaria -c /tmp/xvnc.sh

Se quedará esperando conexiones (verá PORT=5900). Es necesario no cerrar este terminal mientras se quiera tener Ubuntu disponible.

Abrir el escritorio de Ubuntu desde Android

Se puede utilizar cualquier programa de control remot per VNC, que se puede encontrar fácilmente con el Gestor de paquetes F-Droid.

Se conecta a la dirección localhost y con el puerto normal 5900. Sin usuario (nickname) ni tampoco contraseña (password). Tiene un acceso suficientemente seguro porque sólo admitirá conexiones desde el mismo aparato (-localhost).

Salida

Si quiere volver a utilizar Android es suficiente con cerrar el VNC, o símplemente minimizarlo para hacer otras cosas. Si detiene el aparato con Android no pasa nada; es como si tambien detuviera el escritorio de Ubuntu como si fuera un ordenador.

Si quiere detener el sistema Ubuntu sin detener ni reiniciar Android, debe salir de la sesión por el mismo escritorio de Ubuntu, igual como si lo hiciera de un ordenador normal: con el botón gráfico de detener el ordenador, pero la opción de salir como usuario. Si ve una ventana de terminal tambien cerrándola se finaliza la sesión. Con las siguientes indicaciones hará una salida completamente limpia del contenedor.

Detener servicios: En la ventana de Terminal en donde tenía el x11vnc esperando conexiones, si este todavía espera, lo puede interrumpir con {Control} + {C}. Después el resto:

kill $DbusPid
rm -f /var/run/dbus/pid
if [ "$(mount | grep -e "/selinux")" != "" ] ; then umount /selinux ; fi
umount -a
exit

Si por ejemplo ha montado la carpeta de Android /mnt/sdcard :

umount "$PuntoRaiz/mnt/sdcard"
if [ -d /dev/cpuctl ] ; then umount "$PuntoRaiz/dev/cpuctl" ; fi
if [ -d /acct ] ; then umount "$PuntoRaiz/acct" ; fi
umount "$PuntoRaiz/sys"
umount "$PuntoRaiz/dev/pts"
umount "$PuntoRaiz/dev"
umount "$PuntoRaiz/proc"
exit
exit

Para repetir la experiencia

  • Si no ha finalizado la sesión dentro de Ubuntu, símplemente puede volver a conectar con el programa-cliente de VNC.
  • Lo mejor, está claro, es poder tener iconos directos en el escritorio de Android, tanto para montar el contenedor como para conectar con el escritorio por VNC. Este wiki agradecerá mucho las aportaciones sobre este tema.

En otros casos, como por ejemplo que haya detenido el aparato o finalizado el contenedor Ubuntu completamente, escriba estas instrucciones en una ventana de Terminal (datos del mismo ejemplo de esta página, que hay que personalizar):

su
mount -o remount,rw,dev,exec,suid,noatime /data
PuntoRaiz="/data/ubuntu"
mount -o bind "/proc" "$PuntoRaiz/proc"
mount -o bind "/dev" "$PuntoRaiz/dev"
mount -o bind "/dev/pts" "$PuntoRaiz/dev/pts"
mount -o bind "/sys" "$PuntoRaiz/sys"
if [ -d /acct ] ; then mount -o bind "/acct" "$PuntoRaiz/acct" ; fi
if [ -d /dev/cpuctl ] ; then mount -o bind "/dev/cpuctl" "$PuntoRaiz/dev/cpuctl" ; fi
mount -o bind "/mnt/sdcard" "$PuntoRaiz/mnt/sdcard"
chroot "$PuntoRaiz" /bin/su
mount -a
if [ "$(mount)" = "" ] ; then mount -o bind /selinux /selinux ; fi
DbusPid="$(dbus-daemon --system --print-pid --fork)"
NombreUsuaria=usuari
if [ "$Copyrect" = "" ] ; then CrOptions="-nowirecopyrect -noscrollcopyrect" ; else CrOptions="-ncache" ; fi
MoreOptions="-create -localhost -xrandr $CrOptions -rfbport 5900 -nopw -forever -permitfiletransfer -nevershared -scale 1/1"
echo "x11vnc $MoreOptions -env FD_GEOM=${1:-1280x720x16} -afteraccept 'x-session-manager &' -logfile '.x11vnc.log'" > /tmp/xvnc.sh
chmod a+rx /tmp/xvnc.sh
su -l $NombreUsuaria -c /tmp/xvnc.sh

Conectar con la aplicación-cliente de VNC a la dirección localhost y con el puerto normal 5900. Sin usuario ni tampoco contraseña.

Evidentemente lo mejor es tener las instrucciones en scripts (ficheros de texto ejecutables): del primer «mount» hasta el «chroot» en un script en Android (por ejemplo /system/bin/m) y el resto en un script en Ubuntu (por ejemplo /usr/local/bin/x). De esta forma, en un terminal ya sólo habría que hacer:

su
m
x

Y para hacerlo en una sola instrucción, puede cambiar la instrucción chroot "$PuntoRaiz" /bin/su por chroot "$PuntoRaiz" /bin/su -c /usr/local/bin/x , y entonces tambien un script en Android (/system/bin/u) que contenga una sola línea con su -c m . Con esto, inicia el servicio con una sola instrucción en el terminal:

u

(recuerde a dar permiso de ejecución a los scripts, por ejemplo con: chmod 755 /system/bin/u )

Lanzadores en el escritorio de Android

Con el SL4A puede preparar un programillo Bash (Shell script) que tambien se puede ejecutar sin mostrar la ventana de terminal (en background). Con esto puede sustituir «u» que hemos puesto de ejemplo, creando un script llamado por ejemplo Ubuntu.sh y con contenido su -c m

Para crear un icono en el escritorio (Home) que lance la Ubuntu de fondo, oprima el fondo del escritorio durante un rato hasta que abra un menú de opciones, y elija crear un acceso/lanzador personalizado (Custom shortcut). Seleccione la actividad «Scripts» que lleva el icono de los ojos iluminados (SL4A), seleccione su programillo "Ubuntu.sh" y elija que se inicie de fondo/background (botón con engranaje). Le puede acabar personalizando el título como «Ubuntu 0» y acepta.

La misma técnica puede utilizar para crear un lanzador que conecte directamente por VNC: pulsando largamente en el fondo del escritorio, Lanzador personalizado (Custom shortcut), elegir actividad (Pick your activity), Conexión VNC, elegir la de «localhost:5900», póngale un título como «Ubuntu 1» y acepte.

Con estos dos lanzadores, ya tiene la Ubuntu en 2 pulsaciones: primero al icono SL4A que trabaja de fondo, y después al icono de VNC que le conecta. No lance nuévamente el icono de SL4A si no se ha asegurado de que está detenido. Puede conectar y desconectar tantas veces como quiera mientras la Ubuntu esté arrancada de fondo con SL4A.

Un problema detectado: Si se le abre el menú pero no le aparece la opción de crear lanzador/acceso/shortcut en el escritorio (sólo ofrece cambiar el fondo), seguramente está utilizando el escritorio «Trebuchet» que tiene alguna carencia. Puede instalar el gestor de escritorio AnDerWeb para arreglarlo, pero no aprovecha los iconos que tuviera colocados con el anterior.

Como ver las cosas más grandes

Hay aparatos de bolsillo que tienen una gran densidad de puntos en una pantalla táctil, es decir, mucha resolución en una pantalla tan pequeña. Aprovechar toda la resolución en estas situaciones hace difícil acertar los elementos del escritorio con el dedo.

Si en el ejemplo de esta guía queremos ver las cosas el doble de grandes, cambiamos la resolución de 1280x720 por 640x360, y la escala de 1/1 por 2/1. Esto significa dividir por 2 la resolución y aumentar la pequeña imagen al soble para que igualmente llene la pantalla. La operación se puede hacer en cualquier proporción; aquí un ejemplo para hacerlo a dos tercios (que implica un 50% de aumento):

MoreOptions="-create -localhost -xrandr $CrOptions -rfbport 5900 -nopw -forever -permitfiletransfer -nevershared -scale 3/2"
echo "x11vnc $MoreOptions -env FD_GEOM=${1:-853x480x16} -afteraccept 'x-session-manager &' -logfile '.x11vnc.log'" > /tmp/xvnc.sh

1280/3x2 = 853 ; 720/3x2 = 480 ; escala 3/2

Otras fuentes