TELDAT I-router 1104-W. U-Boot (I)

TELDAT I-router 1104-W. U-Boot (I)

 Según la Wikipedia, U-Boot, es la abreviatura del alemán Unterseeboot, «nave submarina», en plural U-Boote, es la denominación dada a los sumergibles y submarinos alemanes desde la Primera Guerra Mundial. El principal escenario donde actuaron fue… , bueno, bromas a parte, vamos a explicar por encima, que es U-boot y como funciona.
 
     U-boot, es básicamente un bootloader libre para dispositivos embebidos, (lo que podríamos llamar una B.I.O.S con funciones de GRUB), es decir, un gestor universal para linux en sistemas embebidos. Este sistema es universal en cuanto a hardware, ya que soporta muchos de los principales sistemas del mercado. Se basa en una serie de archivos de imágenes binarias, en la que su carga y ejecución, se controla mediantes variables de entornos y comandos, y estos acaban agrupándose en scripts, convertidos a imágenes U-boot.
 
     De hecho, un imagen de U-boot, no es más que unos archivos, con una cabecera añadida mediante el comando mkimage de U-boot SDK, estos archivos pueden ser, desde meros archivos texto o por ejemplo un kernel, la cabecera, (usualmente de 64 bits de datos), contiene, un magic number, que identifica que es una imagen U-boot, otros parámetros, como el tipo de archivo que contiene la imagen, a que arquitectura va destinado, fecha de creación, nombre, direcciones de carga, compresión… y un hash del archivo, para comprobar que no se ha modificado la imagen. Por lo que si modificamos un archivo, necesitaríamos crear una nueva imagen.
 

     Un ejemplo aplicado al firmware del Teldat 1104-W, una vez desencriptado:

# file nand-iR4-1.0.4.3.bin
nand-iR4-1.0.4.3.bin: u-boot legacy uImage, Linux-2.6.33.5-iR4-1.0.4.3, Linux/ARM, OS Kernel Image (Not compressed), 1525676 bytes, Fri Jul 6 11:53:13 2012, Load Address: 0x81408000, Entry Point: 0x81408000, Header CRC: 0x6219B186, Data CRC: 0x92BBECF0
El proceso básico de arranque de U-boot, sería:
  • Cargar el u-boot con sus parámetros.
  • Cargar variables de entorno de U-boot
  • Proceder a la carga del Linux embebido.
     Los sistemas embebidos suelen funcionar sin un chip BIOS para abaratar costes de producción y porque realmente no es necesario ya que sus funciones son muy concretas y limitadas, por lo tanto hay que realizar las funciones básicas de otro modo, esta es la función de U-boot. 
 
     Esta imagen tiene que tener capacidad para comunicarse con los distintos dispositivos del sistema embebido, ya que será la encargada de, gestionar la memoria, reproducir alertas sonoras y cualquier otra función que se quiera realizar al iniciar el sistema como mover archivos o conectarse a la red para usar BOOTP. U-boot soporta unos cuantos sistemas de archivos*1: de chip (Flash, MTD, ROM) de memória (tmpfs) y de disco (ramdisk, jffs2, cramfs, ext2…). 
 
     Una vez cargado U-boot y según los parámetros que se le hayan pasado se obtendrá una consola o este iniciará la carga del sistema embebido. 
 
     U-boot admite una serie de comandos que sirven para múltiples propósitos: gestión de dispositivos, extraer información sobre el sistema, mover archivos, control de ejecución… y de variables de entorno que establecen parámetros utilizados por los comandos: resolución de la pantalla, dispositivos a iniciar, tema… 

     Un ejemplo incompleto de las variables de entorno en nuestro Teldat 1104-W:

bootdelay=3
baudrate=115200
eth1addr=00:aa:bb:cc:dd:ff
ipaddr=192.168.0.2
serverip=192.168.0.3
preboot=run preboot1;run preboot2
gatewayip=192.168.0.1
netmask=255.255.255.0
hostname=prg
netdev=eth0
ethact=comcerto_gemac0
nfsargs=setenv bootargs init=${init_process} root=/dev/nfs rw nfsroot=${serverip}:${rootpath}
init_process=/etc/preinit
addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}:${hostname}:${netdev}:off
addeth=setenv bootargs ${bootargs} hwaddress=eth2,${ethaddr}
addtty=setenv bootargs ${bootargs} console=ttyS0,${baudrate}
addmtd=setenv bootargs ${bootargs} ${mtdparts}
boot_nfs=nfs 80600000 ${rootpath}/boot/${kernelfile};run nfsargs addeth addip addtty; bootm 80600000
rootpath=/devel/fs-teldat
kernelfile=uImage
bootfile=u-boot.bin
mtdids=nor0=comcertoflash.0,nand0=comcertonand

La ejecución de estos comandos se puede automatizar mediante scripts, para ello hay que crear un archivo de texto, introducir los comandos que queramos y crear el archivo imagen que ejecutará U-boot, no entraremos en la creación, puesto que no es el objetivo del post.

     Una vez ejecutados los comandos: inicializados los dispositivos, cargado los archivos… se carga el núcleo de Linux pasándole como argumentos los establecidos por la variable bootargs

     Para crear la imagen de Linux con las cabeceras necesarias para U-boot, hay que configurar un kernel y compilarlo con compilación cruzada para la arquitectura destino, esto requiere tener las utilidades necesarias para compilación cruzada

     Ejemplo de carga U-boot completa de nuestro Teldat 1104-W en modo emergencia:

U-Boot 1.1.6 (Mar 4 2011 - 10:29:05) Teldat 1.0.3
Booting from emergency firmware...
DRAM: 256 MB
Comcerto Flash Subsystem Initialization
Flash: 4 MB
NAND: board_nand_init nand->IO_ADDR_R =30000000
256 MiB
In: serial
Out: serial
Err: serial
Reserve MSP memory
Net: comcerto_gemac0, comcerto_gemac1
ethaddr=00:A0:26:7D:59:D4
sernum1=745/014855
sernum2=745/014855

Enter password - autoboot in 3 sec...

## Booting image at 81000000 ...
Image Name: Linux-2.6.21.1-iR4-1.0.3
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 1293808 Bytes = 1.2 MB
Load Address: 81408000
Entry Point: 81408000
Verifying Checksum ... OK
OK
Starting kernel ...

Uncompressing Linux.............................................................

..................... done, booting the kernel.

Linux version 2.6.21.1-iR4-1.0.3 (cgarcia@orion) (gcc version 4.1.2) #1 Fri Mar
4 10:43:41 CET 2011
CPU: ARMv6-compatible processor [4117b361] revision 1 (ARMv6TEJ), cr=00c5387f
Machine: Comcerto 100 (Teldat board)
Memory policy: ECC disabled, Data cache writeback
CPU0: D VIPT write-back cache
CPU0: I cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets
CPU0: D cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets
Built 1 zonelists. Total pages: 62992
Kernel command line: init=/etc/preinit root=/dev/mtdblock4 rootfstype=squashfs r
w console=ttyS0,115200 mtdparts=comcertoflash.0:256k(boot)ro,128k(env),128k(tldt
),1280k(kr),-(fs);comcertonand:2M(kr1),100M(fs1),2M(kr2),100M(fs2),-(cfg) hwaddr
ess=eth2,00:A0:26:7D:59:D4
PID hash table entries: 1024 (order: 10, 4096 bytes)
Dentry cache hash table entries: 32768 (order: 5, 131072 bytes)
Inode-cache hash table entries: 16384 (order: 4, 65536 bytes)
Memory: 248MB = 248MB total
Memory: 248960KB available (2332K code, 270K data, 88K init)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
NET: Registered protocol family 16
L2X0 cache controller enabled
SPI core: loaded version 0.2
Comcerto PCI: init
PCI: bus0: Fast back to back transfers enabled
Generic PHY: Registered new driver
NET: Registered protocol family 2
IP route cache hash table entries: 2048 (order: 1, 8192 bytes)
TCP established hash table entries: 8192 (order: 4, 65536 bytes)
TCP bind hash table entries: 8192 (order: 3, 32768 bytes)
TCP: Hash tables configured (established 8192 bind 8192)
TCP reno registered
SPI core: add adapter comcerto-spi
arm1: Module loaded.
squashfs: version 3.0 (2006/03/15) Phillip Lougher
JFFS2 version 2.2. (NAND) (C) 2001-2006 Red Hat, Inc.
yaffs Mar 4 2011 10:39:30 Installing.
io scheduler noop registered
io scheduler deadline registered (default)
Serial: 8250/16550 driver $Revision: 1.90 $ 2 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO 0x10090000 (irq = 41) is a 16550A
serial8250.0: ttyS1 at MMIO 0x10094000 (irq = 58) is a 16550A
loop: loaded (max 8 devices)
nbd: registered device at major 43
eth0: Comcerto Ethernet Controller 00:ed:cd:ef:aa:cc
eth2: Comcerto Ethernet Controller 00:a0:26:7d:59:d4
Comcerto MDIO Bus: probed
Comcerto MDIO Bus: probed
comcertoflash.0: Found 1 x16 devices at 0x0 in 16-bit bank
Amd/Fujitsu Extended Query Table at 0x0040
number of CFI chips: 1
cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.
5 cmdlinepart partitions found on MTD device comcertoflash.0
Creating 5 MTD partitions on "comcertoflash.0":
0x00000000-0x00040000 : "boot"
0x00040000-0x00060000 : "env"
0x00060000-0x00080000 : "tldt"
0x00080000-0x001c0000 : "kr"
0x001c0000-0x00400000 : "fs"
TCP westwood registered
NET: Registered protocol family 1
NET: Registered protocol family 10
lo: Disabled Privacy Extensions
IPv6 over IPv4 tunneling driver
sit0: Disabled Privacy Extensions
NET: Registered protocol family 17
NET: Registered protocol family 15
802.1Q VLAN Support v1.8 Ben Greear <greearb@candelatech.com>
All bugs added by David S. Miller <davem@redhat.com>
VFS: Mounted root (squashfs filesystem) readonly.
Freeing init memory: 88K
- preinit -
- init -

Please press Enter to activate this console.

BusyBox v1.14.4 (2011-03-04 10:29:46 CET) built-in shell (ash)
Enter 'help' for a list of built-in commands.
 _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 M I N D S P E E D  Technologies - Build v5.2 for Comcerto
 ---------------------------------------------------
root@irouter:/#

En el próximo post, vamos a trabajar sobre el U-boot.