Antes de entrar en materia, lo primero es descargar el kernel que proporciona Orange, nuestro parche contra el mismo y el toolchain (compilador, librerias y utilidades) para poder compilarlo. Tambien el cpio que utilizaremos como sistema de ficheros inicial.
- El kernel puede descargarse aqui
- El toolchain aqui
- El parche con nuestras modificaciones aqui
- El sistema de ficheros aqui
NOTA: Este sistema de ficheros, inicialmente era copiado del router. Ya no lo es. “Nacio” de mi primera compilacion exitosa del Openwrt, mas concretamente la version Kamikaze.
El siguiente paso es descomprimir el toolchain. Mi consejo es que utiliceis un sitio “neutro”, como /opt por ejemplo. Os creara un directorio llamado mips-linux-uclibc. Entramos en este directorio y veremos el “raiz” del toolchain:
bin include info lib libexec man mips-linux mips-linux-uclibc
Como se puede ver, hay directorio bin, lib, include… todo lo necesario para compilar cualquier cosa, aunque en nuestro caso, solo haremos el kernel, que no tiene ninguna complicacion.
MODIFICACION:
Este es un kernel mangoneado -porque no se puede utilizar otra palabra mejor-. Aparte de make o make ARCH=mips clean, poco mas se puede hacer (bueno, si. Se puede hacer make modules y make modules_install). Olvidaros de configurarlo interactivamente. No hay ni (make) xconfig, menuconfig, oldconfig, etc. Quien quiera añadir opciones, modulos, etc, debera añadirselas manualmente al .config que viene “de fabrica”. Y por supuesto debera tener en cuenta que las opciones muchas veces tienen dependencias, que a su vez pueden tener otras dependencias, etc. Quien desee hacer algun cambio, tendra que hacer visita obligada a los ficheros Kconfig correspondientes. Mas aun, por alguna razon esoterica que ignoro, en ocasiones ni siquiera añadiendo al .config sera suficiente. Por mi propia experiencia he descubierto que algunas opciones NO LAS AÑADE en tiempo de compilacion al fichero include/linux/autoconf.h, lo que implica que las ignora por completo. Tendreis que tener mucho ojo con esto.
Como culturilla general sobre este kernel, nada mas añadire que…. Faltan ficheros. Otros sobran. Otros no estan donde deberian estar. Aun otros estan donde no deberian (ojo, no es lo mismo que la anterior). Otros estan horrible y horrorosamente (mal) modificados. En fin, una delicia. Afortunadamente, nuestro parche corrige algunos de estos problemas. Para aplicarlo hacemos:
# patch -p0 < livebox2_kernel.patch
Una vez aplicado el parche, sera necesario que editeis el fichero .config y busqueis y modifiqueis CONFIG_INITRAMFS_SOURCE haciendola apuntar al path donde hayamos copiado el sistema de ficheros cpio.
Por ejemplo:
CONFIG_INITRAMFS_SOURCE="/home/acki/filesystem.cpio"
NOTA: No cambieis la extension del fichero. El nombre puede cambiarse si quereis, pero la extension absolutamente NO.
COMPILACION:
- Primero, actualizaremos el path para que apunte tambien al /bin del toolchain (el que no sepa como hacer esto, mejor que no continue, en serio). Procurad no hacer este cambio permanente, porque de lo contrario tendreis problemas a la hora de compilar el OpenWRT.
- Entramos dentro del directorio donde hayamos extraido el kernel, y simplemente hacemos make. Para los puristas, lo normal seria hacer:
# make ARCH=mips CROSS_COMPILE=mips-linux-uclibc-
Porque, de hecho, si haceis algun cambio en el .config y quereis recompilar limpiamente (el clasico clean), debereis usar:
# make ARCH=mips clean
Porque si no lo haceis asi, intentara hacer un clean de la arquitectura x86, lo cual no es lo que pretendiais hacer.
Una vez compilado el kernel, que como vereis tarda unos pocos minutos, tendreis un hermoso vmlinux en el directorio raiz de los fuentes. Como veis no es un bzImage ni un zImage a los que estamos acostumbrados, y ademas podreis apreciar que tiene un tamaño desproporcionadamente grande. Todos tranquilos, no pasa nada. Es un kernel en bruto, con simbolos e informacion de debug y sin comprimir. Y ademas con un pequeño sistema de ficheros incrustado. Todo esto lo veremos a continuacion.
PREPARACION:
Una vez compilado el kernel, tenemos un vmlinux muy grande, como vimos antes. Ahora vamos a dejarlo en condiciones de ser instalado en el router. En primer lugar, necesitaremos tener instaladas las u-boot-tools. Para debian/ubuntu haremos lo siguiente:
# sudo apt-get install u-boot-tools
Para otras distribuciones, pues ya sabeis, yum, urpmi. zypper…etc.
Una vez instalado el paquete, ya dispondremos de la utilidad mkimage, la que nos creara uImages para usar con nuestro u-boot. Para ello vamos a proceder de la siguiente forma:
- Hacemos un strip al kernel (OJO, un strip MIPS, o sea el strip del toolchain).
# mips-linux-uclibc-strip vmlinux
Como podreis observar, el tamaño ahora es muchisimo menor.
- Ahora obtendremos los puntos de entrada (entry point) y de carga (load address) del kernel. Usaremos readelf. Aqui podemos usar el del toolchain o el estandar de nuestro linux. Al fin y al cabo el formato ELF es igual para todas las arquitecturas:
Elf file type is EXEC (Executable file)
Entry point 0x802fa000
There are 1 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
LOAD 0×002000 0×80010000 0×80010000 0×303086 0x3ab020 RWE 0×2000
* * * * * * * *
Asi, como se observa arriba en rojo, ya tenemos los puntos de carga y entrada.
- Aun nos queda un ultimo paso. Vamos a convertir el kernel a binario. Digamos simplemente que se eliminan las cabeceras ELF. Esto es totalmente necesario, NO saltarse este paso.Usaremos el comando objcopy del toolchain:
# mips-linux-uclibc-objcopy -O binary vmlinux vmlinux.bin
Por ultimo, comprimimos el kernel. Tecnicamente se puede usar compresion bzip2, gzip, lzma y lzo, como dira vuestro mkimage. Yo no he probado otra que no sea gzip, y desconozco las capacidades con las que fue compilado el u-boot. Seguramente funcionen, pero vosotros mismos 
# gzip --best vmlinux.bin
Bien, ya tenemos el kernel en modo binario, comprimido y ademas conocemos la arquitectura y los puntos de carga y entrada. Ya podemos ejecutar mkimage y crear nuestra uImage para metersela al router.
Veamos:
# mkimage -A mips -O linux -T kernel -C gzip -a 0x80010000 -e 0x802fa000 -n "Pruebas" -d vmlinux.bin.gz uImage
Como podeis ver, todos los parametros estan claros. Por si acaso, asi sale en la ayuda del mkimage
-A ==> set architecture to 'arch' -O ==> set operating system to 'os' -T ==> set image type to 'type' -C ==> set compression type 'comp' -a ==> set load address to 'addr' (hex) -e ==> set entry point to 'ep' (hex) -n ==> set image name to 'name' -d ==> use image data from 'datafile'
INSTALACION:
Ahora solo nos queda instalar esta uImage en el router. Es bastante sencillo, pero hay que poner especial cuidado en algunas cosas.
En primer lugar hay que subir la uImage. Desgraciadamente no tenemos red, asi que no nos queda mas remedio que usar el viejo kermit. Tambien, aprovecho para comentar que os recomiendo encarecidamente utilizar el putty como terminal para conectarse al router. NO USEIS el minicom. Tampoco useis el propio kermit como terminal al menos mientras enviais el fichero.
Bueno, procedemos a instalar ambos programas:
# sudo apt-get install ckermit putty
NOTA: Usad mejor el ckermit aunque tengais el gkermit instalado en vuestro sistema. Los de otras distribuciones, ya sabran como hacerlo tambien.
Una vez instalados ambos programas, creamos un fichero de configuracion para el kermit, que llamaremos por ejemplo kermit.cfg. Tal que asi:
set line /dev/ttyUSB0 set speed 57600 set carrier-watch off set flow-control none set prefixing all set parity none set stop-bits 1 set modem none set file type bin set file name lit
Ahora configuraremos el putty asi:


Bien. Conectemonos al router con putty. Tambien con kermit asi:
# kermit /<path>/kermit.cfg
Ahora en el prompt del router hacemos:
# loadb
Y en el kermit:
C-Kermit>send /<path>/uImage
Y a esperar 6 o 7 minutos 
Una vez finalizada la transferencia vereis algo asi en el router:
## Start Addr = 0×80400000
Bien. El router tiene 16MB de flash, que el u-boot mapea desde la direccion 0XBF000000 hasta la 0xBFFFFFFF. La particion BOOT original del router va desde 0xBF000000 hasta 0xBF09FFFF (0xA0000 bytes), por lo que no se podran utilizar direcciones en ese rango. La primera direccion utilizable seria la 0xBF0A0000 entonces. Ademas, hay que tener en cuenta que el tamaño de sector de esta flash es de 128k, o sea, 128*1024 = 131072 = 0×20000. Esto implica que hay que grabar el kernel en cualquier direccion que sea multiplo de 0×20000 (aunque nosotros usaremos 0xBF0A0000 por razones que veremos mas adelante), dado que no se puede empezar a escribir en medio de un sector.. Usad la calculadora. Tomemos como ejemplo la primera direccion libre, la 0xBF0A0000, entonces:
0xBF0A0000 = 3205103616 / 131072 = 24453 EXACTO. Por lo tanto es multiplo y sirve.
Otra al azar:
0xBF57FB8A = 3210214282 / 131072 = 24491,9912872. Va a ser que no. Las mas aproximadas serian 24491 * 131072 y (24491+1) * 131072, o sea, 0xBF560000 y 0xBF580000
Espero que se haya entendido esto aunque solo sea por cultura general.

Volvamos a nuestro router. Lo primero que tenemos que hacer es borrar la parte de la flash que vamos a usar. Usaremos, como dije antes, la direccion la direccion 0xBF0A0000 (no la cambieis u os arrepentireis despues) y el tamaño que nos salio en la subida, en este caso 0x001FF96B (no olvidad el signo + porque asi alinea automaticamente a sector).
# erase 0xBF0A0000 +0x001FF96B ................................................ done Erased 16 sectors
Una vez borrado, procedemos al ultimo paso. Copiar el kernel a flash (hasta ahora estaba en memoria). De nuevo, nos fijamos en los valores de la subida y hacemos (tardara un ratito, paciencia):
# cp.b 0x80400000 0xBF0A0000 0x001FF96B Copy to Flash... done
Listo, ahora ejecutamos:
# bootm 0xBF0A0000
Y tenemos un bonito shell en el router.