Conversión de CIT a Linux

Para poder usar un router Atlas 50 con todas las funcionalidades de Linux tenemos que convertirlo, aplicando unas modificaciones hardware y por supuesto software.

Arquitectura

A continuación se describe la arquitectura hardware del sistema:

  • Microprocesador Motorola MPC 8272.
  • Memoria Caché L1 16KB instrucciones/16KB datos.
  • Memoria SDRAM 64 MB.
  • Memoria FLASH 16 MB.
  • Criptoprocesador integrado.
  • Ranuras de expansión:
    • 1x Ranura de expansión externa PMC-PCI
    • 1x Ranura de expansión interna miniPCI
  • 9 LEDs indicadores de estado

Interfaces ETHERNET

  • 2x Fast-Ethernet 10/100 RJ-45 H
  • Detección automática 10/100 BASE-T
  • Negociación automática Half/Full Duplex
  • Ethernet V2/IEEE 802.3
  • IEEE 802.1Q (VLAN)
  • 2 LEDs de estado por puerto

Interfaz RDSI

  • 1x BRI-RDSI (2B+D) RJ-45

Conversión Hardware

Las interfaces Ethernet no funcionan bien con la arquitectura actual bajo Linux.

Existe un problema de compatibilidad entre un componente hardware de la actual arquitectura con Linux. Esto hace que las interfaces ethernet no funcionen, aunque si el kernel las detecte correctamente.

Para solventarlo, hay que enviar el router en cuestión a Teldat y ellos lo arreglan. Después de arreglarlo, lo devuelven con un bootloader del tipo CIT y un software CIT. Para conseguir la funcionalidad Linux hay que actualizar el bootloader CIT a un bootloader Linux, proporcionado por Teldat.

Adicionalmente se comenta el funcionamiento de alguno de los jumpers de la inferior.

  • Jumper 1 : Test del sistema.
  • Jumper 2 : Actualización del bootloader.

Test del sistema

El jumper 1 realiza un test del sistema, en el cual comprueba que los dispositivos hardware funcionan bien.

Apagar el router mientras se realiza el test del sistema implica que se bloquee el router y/o que se produzca un fallo hardware. No hacer esto bajo ningún concepto

En caso de hacerlo, saldrá el siguiente mensaje:

 UNEXPECTED RESET DURING WARM-UP PROCESS. EQUIPMENT LOCKED. !!!
  
   === INITIAL  MENU ===
  
 a) Change Time
 b) Change Date
 c) Change Code to Run
 d) Change Licence
 e) Load from console (pc_load)
 f) Disk menu
 g) Set default name for file loaded from console
 h) Change BIOS licence
 l) Load from lan
 v) Change version control for loading
 x) Load from console (xmodem)
 z) Change command line (Linux)
 r) Reset
 lram) Load from lan and run without saving
 lk) Load kernel from lan
 lf) Load file system from lan
 0) Exit
    >>

Para desbloquearlo hay que introducir la opción 3 (está oculta).

Conversión Software

Actualizar el bootloader

El jumper 1 permite la actualización del bootloader mediante la consola RS-232 del router. Para ello deberemos colocar el jumper 2 en modo on. Nos saldrá la pantalla de una bios mínima con las siguientes opciones:

  BOOT CODE VERSION: 01.07  Nov 23 2007 17:42:31                                                                                 
    gzip  Nov 23 2007 17:42:31                                                                                                   
  P.C.B.: 93  MASK:0C10  Microcode:00E1                                                                                          
  START FROM EPROM BY SWITCH                                                                                                     
  BIOS CODE DUMP....                                                                                                             
  BIOS DATA DUMP.                                                                                                                
  End of BIOS dump                                                                                                               
                                                                                                                                 
                                                                                                                                 
  BIOS CODE VERSION: 01.07                                                                                                       
  CLK=262144 KHz   BUSCLK=65536 KHz                                                                                              
                                                                                                                             
  SDRAM size: 64 Megabytes                                                                                                       
     BANK 0: 64 Megabytes detected                                                                                               
  FLASH: 16 Mb.                                                                                                                  
  BIOS MAC Add: 00-A0-26-90-FF-FF                                                                                                
  >>                                                                                                                             
  ....                                                                                                                           
  e) Load from console (pc_load)                                                                                              
  x) Load from console (xmodem)                                                                                               
  l) Load from lan                                                                                                            
  m) RTC menu                                                                                                                 
  0) Reset                                                                                                                    
     >>
     

Introducimos la opción x, que nos permite la actualización

  Xmodem whith chk transfer. Default baud rate: 115200                                                                           
  Press any key to change the baud rate                                                                                          
  ..........                                                                                                                     
                                                                                                                             
  Set baud rate to 115200 and send the file with Xmodem with chk protocol.
  When the transfer finish, reset baud rate to 9600.                                                                             
  
  
 e) Load from console (pc_load)
 x) Load from console (xmodem)
 l) Load from lan
 m) RTC menu
 0) Reset
    >>
   

Una vez realizada la actualización realizamos una actualización del kernel siguiendo los pasos de la sección kernel. A continuación instalamos el sistema de ficheros siguiendo los pasos de la sección de sistema de ficheros.

Kernel de recuperación

Durante el proceso de reparación se pensó crear un kernel con las mínimas funcionalidades para tener un sistema base sin red, sólo para acceder a las particiones de disco y tener comunicación al exterior por consola. Para ello se utilizó initramfs, una evolución del sistema initrd, el cual utiliza un disco ram virtual para inicializar el sistema de ficheros. Se puede encontrar más información al respecto en estas direcciones:

Para utilizar este sistema comprimimos un directorio contenedor del sistema de ficheros básico en un archivo cpio. A continuación, en el menuconfig le indicamos la ruta del archivo cpio que contendrá el sistema de ficheros.

Creación del sistema de ficheros

Para que un sistema Linux funcione es necesario un kernel y un sistema de ficheros. En esta parte nos vamos a encargar de crear un sistema básico de ficheros. Para ello vamos a utilizar las librerías compiladas anteriormente con Builroot en la sección Instalación.

Primero, creamos una carpeta raíz.

 >mkdir initramfs
 >cd initramfs

A continuación recreamos las carpetas básicas de un sistema de ficheros:

 >mkdir -p bin dev etc home lib mnt newroot proc root sbin sys

Copiamos las librerías necesarias para el correcto funcionamiento del sistema. En este caso necesitaremos ld-uClibc, libcrypt, libuClibc, libdl, libm, libncurses, libnsl, libpthread, libresolv, librt, libthread_db, libuClibc, libutil.

El sistema de nombres de librerías dinámicas sigue la siguiente notación : <librería>-<x>.<y>.[<z>].so, siendo <librería> el nombre de la librería, <x> e <y> conforman la versión de la librería y <z> es un número de la revisión de la versión que puede aparecer o no. Ya que en una máquina pueden coexistir diferentes versiones de una misma librería, estas se jerarquizan mediante enlaces simbólicos de la siguiente manera:

<librería>-<x>.<y>.so → <librería>-<x>.<y>.[<z>].so

<librería>-<x>.so → <librería>-<x>.<y>.[<z>].so

<librería>→ <librería>-<x>.<y>.[<z>].so

Estos enlaces pueden apuntar a cualquier versión de la librería, pero se suele apuntar a la última versión.

Para crear la jerarquía de librerías lo ideal es copiar todas las librerías de la carpeta original creada por buildroot y eliminar las que no necesitamos. De esta manera nos evitamos el trabajo de crear los enlaces correspondientes

Una vez copiadas las librerías pasamos a poblar la carpeta /dev. Esta tiene que ser copiada mediante el comando *cp -R* (copia recursiva), ya que el algoritmo normal del cp para copia de ficheros lo hace mediante un read/write. Estas llamadas aplicadas a un fichero de tipo dispositivo lo que hacen es leer los datos de ese dispositivo, y copiarlos al destino en forma de fichero normal con *los datos leidos del dispositivo*. Para hacerlo correctamente lo hacemos mediante el siguiente comando:

 >cp -R /dev/ ../initramfs

../initramfs es el directorio contenedor del sistema de ficheros

El siguiente paso es crear los ejecutables necesarios para el funcionamiento del sistema. Para ello usamos Busybox. A busybox lo podríamos llamar “la navaja suiza de los sistemas empotrados”. Nos provee de las herramientas básicas necesarias en cualquier sistema Linux, tales como ls, cp, mkdir, etc.

Esta utilidad es ideal para un sistema empotrado ya que reduce considerablemente el número de líneas de código usadas para las herramientas básicas. Está concebido de tal manera que las funciones comunes a estas herramientas se implementan usa sóla vez y se sabe que función usar mediante un enlace simbólico que apunta al ejecutable de busybox con el nombre de la llamada. Por ejemplo, si tuviéramos instalado busybox con las llamadas ls y cp, existirían dos enlaces simbólicos (ls y cp) que apuntarían a busybox de esta manera:

 >ls -l /bin
 cp -> busybox
 ls -> busybox

Una vez instalado podemos ver que herramientas incluye mediante la siguiente llamada

 >busybox --help

Para esta versión del sistema de ficheros hemos usado la versión 1.14.1 de busybox. La descargamos mediante el siguiente comado:

 > wget http://www.busybox.net/downloads/busybox-1.4.1.tar.bz2

Una configuración básica de las herramientas a usar está en el siguiente archivo de configuración de busybox. Este tiene que ser renombrado a '.config' e incluirlo en el directorio raíz donde se va a compilar busybox.

Definimos el directorio de instalación donde se efectuará la recreación de enlaces simbolicos. Para ello hacemos:

  >make CROSS_COMPILE="powerpc-linux-" menuconfig

Ahora nos vamos a las secciones:

  Busybox Settings  --->
   Installation Options  --->
    (./_install) BusyBox installation prefix 

Y cambiamos el directorio ”./_install al directorio raíz de nuestro sistema de ficheros, por ejemplo '../initramfs'

Ahora lo compilamos con la herramienta make de la siguiente manera:

  >make CROSS_COMPILE="powerpc-linux-"

Hacemos la instalación:

  >make CROSS_COMPILE="powerpc-linux-" install

Por último cambiamos el bit 'suid' del ejecutable busybox.

  >sudo chmod +s initramfs/bin/busybox

El siguiente paso es construir el xmodem. Para ello usamos lrzsz, una versión de xmodem que incluye además ymodem y zmodem. Nos descargamos la versión 0.12.20 de la web oficial. Una vez descargado y descomprimido, ejecutamos los siguientes pasos:

  >./configure --host=powerpc-linux- --target=powerpc-linux- --build=powerpc-linux- --disable-nls
  >make CC=powerpc-linux-gcc CPP=powerpc-linux-gcc RANLIB=powerpc-linux-ranlib LDFLAGS=-s
  > cp {lsz,lrz} ../initramfs/bin

Faltan aún un último detalle, y este es el init. Cuando un sistema Linux se inicia, necesita ejecutar un proceso inicial. Pues bien, este va a ser nuestro fichero init, en forma de un script sh. En esta versión del sistema, tendremos que incluir adicionalmente un fichero en /etc llamado inittab, que indica que otros procesos se requiere iniciar al iniciar el sistema.

El fichero init en / debe existir, de lo contrario el sistema dará un kernel panic

Lo creamos y le damos permisos de ejecución:

  >touch initramfs/init
  >chmod +x initramfs/init

Modificamos el contenido del fichero con nuestro editor favorito y le añadimos el siguiente contenido:

  #!/bin/bash
  exec /bin/bash

Ahora modificaremos el fichero /etc/inittab con lo siguiente

  null::sysinit:/bin/mount -t proc proc /proc
  null::sysinit:/bin/mount -o remount,rw /
  null::sysinit:/bin/mount -a
  null::sysinit:/bin/hostname -F /etc/hostname
  # now run any rc scripts
  ::sysinit:/etc/init.d/rcS
  
  # Set up a couple of getty's
  
  console::respawn:/sbin/getty -L console 115200 vt100
  # Logging junk
  null::sysinit:/bin/touch /var/log/messages
  null::respawn:/sbin/syslogd -n -m 0
  null::respawn:/sbin/klogd -n
  tty2::once:/usr/bin/tail -f /var/log/messages
  
  # Stuff to do for the 3-finger salute
  ::ctrlaltdel:/sbin/reboot
  
  # Stuff to do before rebooting
  null::shutdown:/usr/bin/killall klogd
  null::shutdown:/usr/bin/killall syslogd
  null::shutdown:/bin/umount -a -r
  null::shutdown:/sbin/swapoff -a

Por fin podremos crear nuestro sistema de ficheros, no antes sin poner a todos los archivos el propietario de root.

 >cd initramfs
 >chmod -R root:root .

Creamos el sistema de ficheros con los siguientes comandos

 > cd initramfs
 > find . | cpio -H newc -o > ../initramfs.cpio

Por fin hemos creado el initramfs que incrustaremos en nuestro kernel.

Kernel

Para la creación de nuestro kernel vamos a seguir el mismo procedimiento para obtenerlo y parchearlo que en la sección dedicada a ello: Introducción.

Esta versión del kernel está completamente desprovista de toda funcionalidad de red y de interpretación de caracteres internacionales (cirílico, chino, japonés, etc). Esto es para que ocupe mucho menos espacio y podamos incrustar el sistema de ficheros anteriormente creado. Huelga decir que para los objetivos de este kernel, no requerimos de funcionalidad de red.

Una vez hecho esto, descargamos el archivo de configuración y lo renombramos a '.config', copiándolo al directorio donde hemos descargado y parcheado el kernel. Una vez hecho esto, tenemos que hacer una pequeña modificación en la configuración del kernel para indicarle donde está la imagen de nuestro sistema de ficheros creado para el propósito. Para ello abrimos el menuconfig del kernel:

  >make CROSS_COMPILE=powerpc-linux- ARCH=powerpc menuconfig

Una vez hecho esto, accedemos a las siguientes opciones

 
 General setup  --->
  (../initramfs.cpio) Initramfs source file(s)

En esta opción debemos definir donde se encuentra el archivo contenedor del sistema de ficheros initramfs. Debemos poner la ruta absoluta (empezando por '/') o la ruta relativa al directorio actual.

Una vez hecho esto, compilamos el kernel con:

  >make CROSS_COMPILE=powerpc-linux- ARCH=powerpc 

Deberemos observar en la traza el siguiente mensaje:

  GEN     usr/initramfs_data.cpio.gz
  AS      usr/initramfs_data.o

Esto indica la inclusión del fichero que contiene el sistema de ficheros de initramfs dentro del kernel.

Puesta a punto

Una vez que tenemos el kernel, el siguiente paso es transferirlo a nuestro router. Hay que seguir los mismos pasos del documento Instalación

Al iniciarse el router, pulsamos Ctrl + T y tendremos el siguiente menu:

a) Change Time                                                              
b) Change Date                                                              
c) Change Code to Run                                                      
d) Change Licence                                                          
e) Load from console (pc_load)                                              
f) Disk menu                                                                
g) Set default name for file loaded from console                            
h) Change BIOS licence                                                      
l) Load from lan                                                            
v) Change version control for loading                                      
x) Load from console (xmodem)                                              
z) Change command line (Linux)                                              
r) Reset                                                                    
lram) Load from lan and run without saving                                  
lk) Load kernel from lan                                                    
lf) Load file system from lan                                              
0) Exit                                                                    
>>

Pulsamos la x (Load from console) y transferimos el kernel al router. Una vez hecho esto pulsamos la opción z (Change command line) para cambiar la linea de comandos inicial. Esta será una muy básica, la que viene por defecto en el router. Será la siguiente:

  console=ttyCPM0,9600n8n

Una vez hecho esto ya podemos inicializar el sistema. Pulsamos 0 para salir.

Manejo de router

Ahora disponemos de nuestro router con una funcionalidad básica podemos leer y escribir en cualquier partición de su memoria.

  • Partición 0 (mtdblock0):Bootloader
  • Partición 1 (mtdblock1):Kernel
  • Partición 2 (mtdblock2):Sistema de ficheros normal (no initramfs)
  • Partición 3 (mtdblock3):Reservada para logs en la versión original de CIT

Leer una partición

Este kernel se creó originalmente para leer y escribir en las particiones del router, ya que sin saber que el router no era compatible con Linux a priori, intentamos hacer una conversión de un router CIT a un router Linux. Para comprobar que el bootloader se actualizaba correctamente necesitábamos leer una de las particiones y comprobar que el contenido era el esperado.

Para leer una partición y guardarla en un formato binario se utiliza el mandato dd (data dump). Tiene muchas opciones, muchas de las cuales afectan al rendimiento de la operación, pero las que nos van a interesar son las siguientes:

  • if=<origen> : Especifica el origen de donde se va a leer (archivo o dispositivo). Si no se especifica lee de la entrada estándar.
  • of=<destino> : Especifica el destino donde se va a escribir (archivo o dispositivo). Si no se especifica escribe en la salida estándar.
  • bs=<tamaño> : Especifica el tamaño de bloque para la entrada y la salida.
  • count=<destino> : Especifica el numero de bloques que serán leídos y escritos.

En concreto para leer la partición del bootloader lo hacemos con el siguiente comando:

  >dd if=/dev/mtdblock0 of=bootloader.bin

Escribir en una partición

Si tenemos una imagen de una partición y volcar byte a byte esa imagen en la partición el procedimiento será el siguiente:

 >dd if=imagen.bin of=/dev/mtdblock2

Recepción por consola

Dado que no tenemos activada la funcionalidad de red, no podemos transferir archivos al router por NFS y necesitamos pasar esos archivos por consola. El dispositivo que controla la consola es /dev/console y a priori está configurado para una velocidad de transmisión de 9600 baudios.

El programa lrz es compatible con los protocolos de transferencia xmodem, ymodem y zmodem. En nuestro caso, dado que el minicom acepta los tres protocolos también, utilizaremos el zmodem, por ser el último desarrollado y el más eficiente. La sintaxis del mandato es:

  >lrz [opciones] [nombre.del.fichero.si.usamos.xmodem]

Algunas opciones interesantes pueden ser:

  • -Z: Se usa el protocolo zmodem.
  • –ymodem : Se usa el protocolo ymodem.
  • -X: Usa el protocolo xmodem.
  • -O : Desactivar los timeouts. Se espera para siempre por datos
  • -r : Intenta continuar la transferencia de ficheros desde donde se dejó en una transferencia anterior.

Ahora pongamos por ejemplo que ya hemos dado la órden en nuestra estación de trabajo para transferir el fichero 'file1.bin'. Para la recepción de este fichero en nuestro router usando el protocolo zmodem ejecutamos el siguiente mandato:

 >lrz -Z

Este protocolo tiene características interesantes como el autonegocio de la velocidad de tranferencia, comprobación redundante de errores y que no hace falta especificar el nombre del fichero que se va a transferir, ya que mantiene el que se le ha dado en el emisor.

Envío por consola

Ahora se da la situación inversa: queremos enviar un archivo desde nuestro router a nuestra máquina de trabajo. Dado que no están activas las funciones de red, deberemos hacerlo por consola. El dispositivo que controla la consola es /dev/console y a priori está configurado para una velocidad de transmisión de 9600 baudios.

El programa lsz es compatible con los protocolos de transferencia xmodem, ymodem y zmodem. En nuestro caso, dado que el minicom acepta los tres protocolos también, utilizaremos el zmodem, por ser el último desarrollado y el más eficiente. La sintaxis del mandato es:

 >lsz [opciones] fichero

Algunas opciones interesantes pueden ser:

  • -Z: Se usa el protocolo zmodem.
  • –ymodem : Se usa el protocolo ymodem.
  • -X: Usa el protocolo xmodem.
  • -O : Desactivar los timeouts. Se espera para siempre por datos
  • -r : Intenta continuar la transferencia de ficheros desde donde se dejó en una transferencia anterior.
  • -8 : Prueba a transferir en bloques de 8k.

Imaginemos que hemos sacado conseguido trasladar la partición del bootloader a un fichero binario. Ahora queremos enviar ese fichero a nuestra máquina para analizarlo. Se haría mediante el siguiente comando:

 >lsz -Z8 bootloader.bin

En nuestra máquina deberemos dar la instrucción al minicom de que reciba el fichero por el protocolo zmodem.Se puede observar que indicamos el uso del protocolo zmodem mediante la opción -Z y prueba a enviar bloques de 8 kbytes. Dado que el cable es corto y no se suelen producir muchos errores de transferencia, es recomendable el uso de esta opción para reducir la comprobación de errores de redundancia cíclica.

Desensamblar el bootloader

Como último detalle se ha conseguido desensablar el bootloader del dispositivo. Para ello hay que sacarlo del router con los pasos anteriormente mencionados. Para desensamblar el bootloader se utilizará la utilidad objdump, contenida en el paquete binutils. Este se habrá compilado en la máquina de desarrollo para desarrollo cruzado al crear el toolchain con la utilidad buildroot, tal como se explica en la sección Instalación.

El bootloader no está en formato ELF,sino en EST flat binary. Este formato es el usado para UClib y no incluye símbolos, es el código “tal cual”. Dado esto, es muy dificil de depurar y sólo tiene utilidad para ver qúe es lo que hace el código que queremos desensamblar.

Una vez que tenemos el bootloader vemos que tipo de fichero es con la utilidad file:

  > file bootloader.bin
  bootloader.bin: EST flat binary

Como vemos, es de tipo EST. Este target se llama binary. El mandato objdumpp tiene el siguiente formato:

  >objdump <opcion(es)> <archivo(s)>

Vamos a describir ahora las opciones que no serán útiles:

  • -a : Muestra las cabeceras del archivo
  • -l : Incluye el nombre del archivo y el número de la línea en el dump
  • -D : Desensabla todas las secciones.
  • -x : Muestra el contenido de todas las cabeceras
  • –special-syms : Muestra símbolos especiales
  • –target=<target>: Define en que formato está el archivo que queremos convertir. Nos va a interesar la opción binary.
  • –architecture=<arq>: Define para que arquitectura está compilado. La nuestra será powerpc:603.

Una vez definidas las opciones, desablaremos nuestro bootloader con el siguiente mandato:

  >powerpc-linux-objdump -alxD --special-syms --target=binary --architecture=powerpc:603 bootloader.bin > bootloader.s

El fichero “bootloader.s” es a donde se redirecciona la salida del objdump y contendrá el código en ensamblador del fichero bootloader.bin.

Huelga decir que para el target binary (EST flat binary), no está muy lograda la interpretación de las instrucciones. Al editarlo para dejar sólo las opcodes, el compilador de ensamblador GNU as da bastantes fallos. Creemos que esto se solucionaría si interpretáramos un archivo ELF con todos sus símbolos de depuración

Conversión entre formatos objeto

Nos puede interesar convertir un fichero objeto de un formato a otro (de ELF a EST o viceversa). Para hacer esto tenemos un programa llamado objcopy, que convierte un ejecutable de un formato a otro. La sintaxis de este mandato es:

  >objcopy [opcion(es)] archivo(s)_entrada [archivo(s)_salida]

Algunos parámetros que nos interesan son los siguientes:

  • –input-target <target> : target (tipo de archivo) de entrada.
  • –output-target <target> : target (tipo de archivo) de salida.

Para convertir un ejecutable ejecutamos el siguiente mandato:

  >powerpc-linux-objcopy --input-target binary --output-target elf32-powerpc bootloader.bin bootloader_elf.bin
 
proyectos/teldatsi/conversion.txt · Última modificación: 2012/10/08 17:58 (editor externo)
 
Recent changes RSS feed Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki