Archivo por días: 13 agosto, 2013

Wifi, sonido y mas

Actualizado. Después de mucho pelearme con mi tablet, finalmente he conseguido que funcionen casi todos los dispositivos. También he pulido el proceso de instalación de Linux; de hecho hay bastantes cosas que cambiar del artículo anterior, así que vamos allá.

El fichero SCRIPT.BIN

En primer lugar quería disponer del fichero script.bin original de mi tablet, y no de uno creado para otro dispositivo, porque obviamente podía haber algún parámetro (velocidad de memoria, puertos de dispositivos, etc) que tuviese un valor diferente, evitando que funcionase algún dispositivo. De hecho, una vez que conseguí utilizarlo, el sonido funcionó automáticamente (antes no detectaba ninguna tarjeta de sonido).

El proceso para obtener dicho fichero bin no fue sencillo: dicho fichero está en la flash interna de la tablet, pero por desgracia no tenía acceso a ella desde Linux (no detecta dicho dispositivo) ni desde Android (lo detecta, obviamente, pero no tengo permisos de acceso por no tener la tablet rooteada. Además, al ser la partición de arranque, no se monta una vez lanzado Android, por lo que tampoco está disponible desde éste). Tras muchos intentos encontré la solución: utilizar el ADB (Android Debug Bridge). Esto permite acceder a un dispositivo Android desde un PC. Para ello, una vez instalado el kit de desarrollo de Android, basta conectar la tablet al PC a través de un puerto USB, ir al directorio sdk/platform-tools y ejecutar:

    sudo ./adb start-server
    ./adb shell
    cat /dev/block/mmcblk0p1 > punto_de_montaje_de_tarjeta_SD/particion1.img
    exit
    sudo ./adb kill-server

El primer comando lanzará como root el servidor ADB, que se conectará a nuestro dispositivo, y el segundo lanzará una shell como root en él. El tercero, ejecutado ya desde la shell del dispositivo, volcará la primera partición de la flash en el fichero particion1.img de la tarjeta SD. Por último, salimos de la shell y desactivamos el servidor ADB.

En ocasiones adb no encuentra nuestro dispositivo. Si tecleando ./adb devices no aparece ningún dispositivo detectado, es posible que adb no tenga a nuestro fabricante en su lista. Para añadirlo manualmente hacemos un lsusb, y vemos el identificador de nuestra tablet. Digamos que es AAAA:BBBB (dos números en hexadecimal de cuatro cifras cada uno). Sólo tenemos que editar ~/.android/adb_usb.ini y añadir en él 0xAAAA, reiniciar el servidor adb, y listo.

Ahora sólo tenemos que llevar el fichero particion1.img a un PC con linux y montar dicha partición, por ejemplo en /mnt:

    sudo mount -o loop particion1.img /mnt

Ahí encontraremos el fichero script.bin, que podremos convertir en un fichero .fex mediante la utilidad bin2fex, que encontraremos en el repositorio sunxi-tools. De hecho es necesario hacerlo para poder hacer un par de modificaciones, sin las que nuestro Linux no arrancaría desde la tarjeta SD. En concreto éstos son los cambios:

@@ -12,7 +12,7 @@
 pll4_freq = 960
 pll6_freq = 720
 power_start = 0
-storage_type = 2
+storage_type = 1

 [pm_para]
 standby_mode = 0
@@ -445,7 +445,7 @@
 sdc_wp =

 [mmc2_para]
-sdc_used = 1
+sdc_used = 0
 sdc_detmode = 3
 bus_width = 8
 sdc_cmd = port:PC06<3><1><3><default>
@@ -510,7 +510,7 @@
 usb_id_gpio =
 usb_det_vbus_gpio =
 usb_drv_vbus_gpio = port:power203<1><0><default><0>
-usb_host_init_state = 0
+usb_host_init_state = 1

 [port_pm]
 restrict_1a = 0

El primero cambia el tipo de almacenamiento de Flash a SD. El segundo especifica que no se active la memoria Flash interna (si se activa, no arranca el sistema). Por último, el tercero activa desde el principio el segundo USB, necesario para que funcione la red WiFi.

Existe una lista con todas las opciones de un fichero FEX, útil si se quieren hacer más cambios manuales.

Una vez hechos estos cambios ya podemos generar el fichero script.bin final, siguiendo el método indicado en el artículo anterior.

El kernel

En el núcleo también hay que hacer algunos cambios. Para empezar, hay que utilizar la versión 3.4, en lugar de la 3.0, porque es la que tiene soporte para la tarjeta de red:

    git clone -b sunxi-3.4 https://github.com/linux-sunxi/linux-sunxi linux-3.4-sunxi
    cd linux-3.4-sunxi

De todas formas, el chip que lleva esta tablet es el Realtek RTL8188etv. Aunque en teoría es compatible con el driver para la familia RTL8188, en la práctica hay que añadir una línea para que reconozca el identificador USB de este chip concreto. Aunque ya envié el parche a la lista de correo, lo añado aquí porque no se cuanto tardarán en añadirlo:

diff --git a/drivers/net/wireless/rtl8188eu/os_dep/linux/usb_intf.c b/drivers/net/wireless/rtl8188eu/os_dep/linux/usb_intf.c
index 5f4390a..df9d488 100644
--- a/drivers/net/wireless/rtl8188eu/os_dep/linux/usb_intf.c
+++ b/drivers/net/wireless/rtl8188eu/os_dep/linux/usb_intf.c
@@ -185,7 +185,8 @@ static struct usb_device_id rtw_usb_id_tbl[] ={
 #endif
 #ifdef CONFIG_RTL8188E
        /*=== Realtek demoboard ===*/           
        {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8179)},//Default ID        
+       {USB_DEVICE(USB_VENDER_ID_REALTEK, 0x0179)},//rtl8188etv ID (szenio 1207 tablet)
 #endif
        {}      /* Terminating entry */
 };

Una vez aplicado este cambio de una única línea, podemos ya proceder a configurar el núcleo. Para ello partimos de la configuración genérica para el A13:

    make ARCH=arm a13_defconfig
    make ARCH=arm menuconfig

Estas son las opciones que he modificado:

    General Setup
        POSIX message queues=Y
    Device Drivers
        Network Device Support
            Ethernet (10 or 100Mbit)=N
            Wireless LAN
                Realtek 8188E USB WiFi=M
        Character Devices
            Non-standard serial port support=N
            Serial drivers
                8250/16550 and compatible serial support=N
        Graphics support
            Console Display driver support
                Map the console to the primary display device=Y
            Bootup logo=Y
    Security Options
        Enable the securityfs filesystem=N

Una vez hecho, podemos ya proceder a compilarlo, pero con el compilador que utilice la gnueabihf (que utiliza coma flotante por hardware, en lugar de la gnueabi, como hacía en el artículo anterior). Para ello primero necesitamos instalar esta versión del compilador:

    sudo apt-get install gcc-4.7-arm-linux-gnueabihf gcc-arm-linux-gnueabihf

y ya podemos compilar el núcleo en sí:

    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImage
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=out modules
    make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- INSTALL_MOD_PATH=out modules_install

Los ficheros boot.cmd y boot.scr

El último cambio respecto al artículo anterior está en el fichero boot.cmd (y su fichero hijo boot.scr). Este fichero contiene los parámetros de arranque del núcleo, y es básicamente un script para U-Boot. En nuestro caso, crearemos el fichero boot.cmd en la partición VFAT de nuestra tarjeta SD con este contenido:

    setenv bootargs console=ttyS0,115200 root=/dev/mmcblk0p2 rootwait panic=10 ${extra}
    fatload mmc 0 0x43000000 script.bin
    fatload mmc 0 0x48000000 uImage
    bootm 0x48000000

y lo compilaremos con:

    mkimage -C none -A arm -T script -d boot.cmd boot.scr

Y listo. Si en algún momento queremos cambiar las opciones de arranque de nuestro núcleo, sólo tendremos que editar el fichero boot.cmd, añadirlas en la primera línea y recompilarlo. Existe una página con todas las opciones del núcleo específicas de sunXi.

Encender y apagar el sistema

De momento no está activa la gestión de energía, por lo que si se hace un halt o un shutdown -h now, el sistema parecerá apagarse, pero en realidad seguirá encendido. En estos casos, para apagarlo «de verdad» es necesario mantener pulsado el botón de encendido durante seis o más segundos.