martes, 5 de junio de 2007

Router Hack

El problema de comunicación y procesamiento de alto nivel se solucionó utilizando un sistema embebido extraído de routers Linksys. Para efectos de prueba se utilizó la referencia WRT54GL, mientras que para el sistema real se utilizó la referencia WRTSL54GS.

Para estos routers se ha desarrollado una distribución Linux denominada Openwrt, la cual es libre y puede ser descargada desde www.openwrt.org. La versión utilizada es la WhiteRussian 0.9, la cual incluye el kernel 2.4 de linux. Al momento de escribir estas líneas está próxima a salir la versión 1.0 de OpenWrt, primera versión estable, denominada Kamikaze.

A continuación se describe el proceso de hacking llevado a cabo:

PASO 1:

Descargar el openwrt al router.

Lo primero es montarle el sistema operativo linux al sistema embebido, por lo tanto, es necesario descargar la imagen desde el servidor de openwrt. Existen tres tipos de imágenes para tal fin:

  • micro

  • bin

  • pptp.

La primera es una versión reducida de Openwrt, incluye menos paquetes, por lo tanto, también pesa menos. Las siguientes se diferencian en los paquetes de PPP; la primera incluye pppoe (Point-to-Point Protocol Over Ethernet), la segunda el pptp (Point-to-Point Tunneling Protocol). Se escogió la bin para montar sobre el router.

Existen diversas maneras de montar el SO en el router. En nuestro caso se escogió la instalación mediante la herramienta de actualización de firmware que provee el Software propietario de Linksys. La imagen del Openwrt viene en formato TRX, la cual es la imagen tal cual se copiará en la memoria Flash del dispositivo. Es posible también descar la imagen con extensión BIN, este formato está soportado por el software de Linksys para las imágenes de actualización de firmware. En este caso, se descargó de http://downloads.openwrt.org/whiterussian/newest/default/, el archivo openwrt-wrt54g-squashfs.bin para el wrt54gl, o el openwrt-wrtsl54gs-squashfs.bin para el wrtsl54gs.

Se monta el firmware en la interfaz que provee el router a través de su servidor http. Se recomienda realizar la actualización de firmware de manera cableada, no inalámbrica, puesto que puede poner problemas. Asegúrese que las conexiones de alimentación estén bien realizadas, puesto que si el router se apaga durante la actualización de firmware, no volverá a arrancar (en caso de que esto suceda, no todo está perdido, remítase a: http://wiki.openwrt.org/OpenWrtDocs/Installing ).

Al bootear el sistema, se cargará el nuevo firmware. La configuración anterior se mantiene, por lo tanto, su router debe de estar corriendo tal cual lo estaba haciendo antes de realizar la actualización. Al ingresar nuevamente al portal de administración del router, notará que ha cambiado, puesto que ahora se está corriendo la aplicación webif del Openwrt, la cual es la consola de administración vía web.


Lo primero que se debe hacer es cambiar la contraseña. Esto se puede realizar a través de la página, por System -> Password Change. Otra opción sería conectarse vía telnet al router. ESto es, en un shell, escribir:

telnet 192.168.1.1


Asumiendo que esa es la dirección del router.

Ya dentro deberá utilizar el comando passwd, y digitar la contraseña.

La interfaz web se queda realmente corta en cuanto a configuración de parámetros del router se refiere. Es preferible realizar cualquier modificación ingresando directamente al sistema operativo a través de un shell. Para esto se utiliza ssh, el cual viene instalado por defecto en las distribuciones de linux. Para windows, es posible utilizar el SSH CLIENT, el cual se consigue a través de la red. Basta entonces con ingresar en consola: ssh root@192.168.1.1, para estar dentro del sistema.




PASO 2:

Debido a la corta memoria que trae el router WRT54GL para almacenamiento (4 Mb), además de que el Openwrt ocupa casi toda esta cantidad, se hace necesaria una modificación para permitir tener más espacio en memoria persistente, de tal manera que sea posible la instalación de más software para el router. Por lo tanto, se realizaron las siguientes modificaciones en el router, de tal manera que soportara una tarjeta SD, y así expandir la memoria hasta 128 Mb para nuestro caso. Estas modificaciones no serán necesarias para el WRTSL54GS, debido a que la capacidad de este es el doble del anterior, e incluso éste posee un puerto USB, a través del cual es posible conectar una USB Flash y así aumentar la capacidad de almacenamiento. De todas maneras, es posible realizar esta modificación.

Las modificaciones hardware se presentan en el siguiente documento, tomado de: euskoin.net/docu/SD-WRT54GL.pdf, o también se pueden basar de la siguiente página: http://www.altred.net/cgi-bin/moin.cgi/SD_MOD. Las modificaciones software presentadas en el anterior documento no presentaron buenos resultados, por lo tanto se hizo lo siguiente:

Instalación de módulos

Se descarga el módulo vfat con el comando:

root@nxbot:/# ipkg install kmod-vfat

El módulo mmc.o lo tuve que descargar de otra dirección, la que está en el documento es inexistente. (descarga el módulo de aqui). El módulo lo monte al router mediante scp, directamente a la carpeta /lib/modules/2.4.30.

Ahora se procede a insertar los módulos en el kernel para que sean utilizados. Esto se hace mediante insmod:

root@nxbot:/# insmod fat

root@nxbot:/# insmod vfat

root@nxbot:/# insmod mmc

Procedemos a ver entonces el log, que nos permite ver los mensajes que bota el kernel, de tal manera que podamos verificar si la tarjeta fue reconocida. Este comando debe mostrar las siguientes líneas:

.

.

.

[INFO] mmc_hardware_init: initializing GPIOs

[INFO] mmc_card_init: the period of a 380KHz frequency lasts 524 CPU cycles

[INFO] mmc_card_init: powering card on. sending 80 CLK

[INFO] mmc_card_init: 80 CLK sent in 43668 CPU cycles

[INFO] mmc_card_init: resetting card (CMD0)

[INFO] mmc_card_init: doing initialization loop

[INFO] mmc_card_init: card inited successfully in 7 tries (216141 CPU cycles).

[INFO] mmc_init: MMC/SD Card ID:

18 49 4e 31 32 38 4d 42 04 40 a5 75 7e 00 62 63 [INFO] Manufacturer ID : 18

[INFO] OEM/Application ID: IN

[INFO] Product name : 128MB

[INFO] Product revision : 0.4

[INFO] Product SN : 40a5757e

[INFO] Product Date : 2006-2

[INFO] mmc_card_config: size = 122752, hardsectsize = 512, sectors = 245504

[WARN] mmc_init: hd_sizes=122752, hd[0].nr_sects=245504

[INFO] mmc_card_init: set_blocklen (CMD16) succeeded !

Partition check:

mmca: p1

.

.

.

.

Aunque pueden variar un poco de acuerdo al módulo mmc.o utilizado, y obviamente a la tarjeta SD utilizada, lo importante debe ser que pueda ser reconocida, y no muestre ningún mensaje de error. Como se puede ver en este caso, la tarjeta es de 128MB y tiene una sola partición.


Montaje automático de la SD


Para que la tarjeta se montara automáticamente al iniciar el router, se realizaron las siguientes modificaciones:

Se modificó el archivo fstab (en mi caso no existía):


root@nxbot:/# vi /etc/fstab


Y en el archivo escribimos:

/dev/mmc/disc0/part1 /mnt/sd/ vfat defaults 0 0

Así, en el momento de montar la tarjeta, ésta se montará con formato vfat.


Se creó un módulo para que montara automáticamente la tarjeta, en /etc/init.d:

root@nxbot:/# vi /etc/init.d/S51mount


Y se agregan las siguientes líneas:


#!/bin/sh

echo "0x9C">/proc/diag/gpiomask

insmod mmc

mkdir /mnt/sd

mount /dev/mmc/disc0/part1


La línea echo “0x9C”>/proc/diag/gpiomask es de las más importantes de este archivo. Al realizar la modificación de la tarjeta SD, se están utilizando las líneas GPIO disponibles en el router. OpenWRT utiliza estas líneas para entrar en un estado denominado “failsafe mode”. Por lo tanto, se debe aplicar una máscara, que debe ser introducida en el archivo /proc/diag/gpiomask. Esta máscara define que líneas GPIO se están utilizando, y que no deben ser tenidas en cuenta para entrar al modo anteriormente mencionado. Se utilizó el hexadecimal 0x9C, debido a que se están utilizando las líneas GPIO 2, 3, 4, 7. Asumiendo un byte, se coloca un 1 a cada posición de línea GPIO que se vaya a utilizar, por lo tanto resulta 10011100, que en su equivalente hexadecimal es justamente 0x9C. Se menciona esto puesto que algunas modificaciones para utilizar la tarjeta SD, usan otras líneas GPIO, por lo tanto es común ver otras máscaras utilizadas.

Las otras líneas se preocupan por montar la partición. No es necesario poner la carpeta de destino en el comando mount, puesto que en fstab ya se ha establecido en que carpeta deberá ser montada esta partición.

Finalmente se deben cambiar los permisos del archivo, de tal manera que pueda ser ejecutado:

root@nxbot:/# chmod 777 /etc/init.d/S51mount


Para que estas modificaciones tomen efecto, será necesario reiniciar el sistema:

root@nxbot:/# reboot


Instalación y ejecución de programas montados en la SD

Para poder instalar programas y aplicaciones en la tarjeta SD, es necesario seguir los siguientes pasos.


Usar ipkg para instalar aplicaciones directamente en la SD:


Se debe modificar el archivo ipkg.conf ubicado en /etc:

root@nxbot:/#vi /etc/ipkg.conf


y se agrega la línea:

dest sd /mnt/sd


En caso de que la tarjeta sd haya sido montada en otro directorio, cambiar la ruta de la línea.

Así, al ejecutar el comando ipkg, se puede utilizar la opción -d para definir el directorio de instalación. Por ejemplo, para instalar el paquete lighttpd en la tarjeta sd, se utilizaría el siguiente comando:

root@nxbot:/# ipkg install -d sd lighttpd


Para que los programas puedan ser ejecutados sin importar en que directorio el usuario esté ubicado, es necesario modificar la variable PATH. Para esto se modifica el archivo /etc/profile

root@nxbot:/# vi /etc/profile


y se modifica la línea de PATH, agregándole los directorios donde se encontrarán los ejecutables de las aplicaciones en la tarjeta sd, /mnt/sd/bin, /mnt/sd/sbin, /mnt/sd/usr/bin, /mnt/sd/usr/sbin, de la siguiente manera:


export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/mnt/sd/bin:/mnt/sd/sbin:/mnt/sd/usr/bin:/mnt/sd/usr/sbin

export LD_LIBRARY_PATH=/lib:/usr/lib:/mnt/sd/lib:/mnt/sd/usr/lib


viernes, 1 de junio de 2007

Player/Stage

Player es un servidor para el control de robots móviles, este se comporta como una capa de abstracción entre los dispositivos del robot y el controlador, además brinda capacidad para interconexión vía TCP/IP. El player fue originalmente creado para la plataforma Pionner 2DX, pero al ser un proyecto de software libre y tener una buena aceptación por parte de muchos centros de investigación en el mundo se ha extendido y ahora soporta mas plataformas como Khepera, Romba, Nomad, Segway RPM y otras mas.

Player corre sobre el sistema operativo GNU/Linux, este software fue escogido para el proyecto por su versatilidad y porque brinda la posibilidad de trabajar tanto robots reales como también simulados, esto ultimo en conjunto con el simulador stage del que se hablara mas adelante.

Al utilizar player trabajamos sobre una arquitectura cliente-servidor donde el player sera el servidor instalado sobre el robot, el cliente se comunicara vía TCP/IP y por este medio solicitara información sensorial del robot y enviara comandos a este y a los diferentes dispositivos conectados a el.

Para comprender el funcionamiento del player es necesario conocer dos conceptos utilizados en su arquitectura: dispositivo e interfaz.

Un dispositivo es cualquier elemento que provea información o reciba comandos para realizar alguna acción sobre el ambiente, todo sensor o actuador es tratado como un dispositivo en el player, de esta forma un robot se ve como un grupo de dispositivos conectados al servidor y a los cuales el cliente puede acceder.

Una interfaz es una abstracción que agrupa un grupo de dispositivos similares en funcionalidad y brinda un grupo de métodos comunes para su interacción con el cliente.

Player brinda un grupo de interfaces comunes para ciertos tipos de dispositivos. Por ejemplo, dados dos sistemas de control de posición, existe una interfaz común para ambos en este caso la interfaz position2d. Este tipo de arquitectura permite que luego de que exista el driver de un dispositivo, no sea necesario a la hora de construir el controlador tener en cuenta los detalles de funcionamiento del hardware a utilizar, algo similar a la capa de abstracción de hardware del sistema operativo Linux.

Player esta construido en C++ pero el cliente puede ser programado en cualquier otro lenguaje que soporte comunicación TCP/IP, hay disponibles muchas librerías en diferentes lenguajes que facilitan el desarrollo de los controladores.

Además de drivers para hardware existen también dentro del player drivers abstractos, por ejemplo drivers para algunos algoritmos de posición como amcl, el cual es una implementación del algoritmo de localización adaptativo Monte Carlo.

Stage es un simulador de robots móviles, este se puede utilizar como un API para desarrollar simuladores o en conjunto con el player como simulador independiente.

El stage esta orientado al trabajo en robótica cooperativa brinda la posibilidad de simular poblaciones de robots y dispositivos con modelos computacionales simples.