
Este documento esta dedicado a Sultanovich.
Una de las grandes ventajas de Linux es su portabilidad y su capacidad de ser adaptado a tal punto que lo hace ideal para sistemas empotrados o embeded.
Les propongo hacer el siguiente experimento. Diseñar una minidistro que ocupe escasamente un disquete y sea totalmente funcional.
Componentes que vamos a necesitar:
-Nuestra distro favorita
-compilador gcc
-Fuentes del kernel
-Busybox
-genromfs
Empezando:
Para el que todavia no sabe un sistema operativo se compone del kernel y de las utilerías básicas para poder interactuar y darle ordenes al sistema. Por ello el nombre GNU/Linux.
Hoy en día cualquier instalación básica (sin componentes adicionales como la interfaz gráfica, etc) ocupa un poco mas de 100MB.
Ahora como vamos a hacer para meter todo eso en un disquete?
Fácil, gracias a la magia de un verdadero genio, Bruce Perens, que diseño Busybox para el disquete instalador o de rescate de Debian.
Utilizó el concepto de Multi-call executable que consiste en armar links con los diferentes comandos a un archivo, para luego en caso de ser necesario llamarlos por los nombres de los links. La idea es lograr comprimir todas la utilería básica del sistema en un uniln co archivo.
Para verlo mas gráficamente, supongamos que compilamos busybox a mano y queremos que tenga e comandos básicos:
# ln busybox ls
# ln busybox cp
# ln busybox rmdir
Por lo tanto si ejecutamos ls en realidad estaríamos llamando al programa que se encuentra en el archivo único busybox.
Si hacemos ls -il busybox ls cp rmdir obtendremos algo asi:
173456 -rwxrwxr-x 4 root root 234354 Dec 8 8:22 busybox
173456 -rwxrwxr-x 4 root root 234354 Dec 8 8:22 ls
173456 -rwxrwxr-x 4 root root 234354 Dec 8 8:22 cp
173456 -rwxrwxr-x 4 root root 234354 Dec 8 8:22 rmdir
En este caso vemos el primer campo que indica el numero de inode. Como podrán ver todos los archivos están ocupando el mismo inode por lo tanto ocupan el mismo espacio.
No son 4 archivos sino 4 nombres de 1 archivo.
Pueden bajar busybox en su ultima versión del site oficial http://www.busybox.net/ o bien bajarlo de los repositorios oficiales de su distro favorita.
Una vez bajado tenemos dos opciones para compilarlo: estático o dinámico.
Todo depende de lo que quieran hacer. En nuestro caso lo vamos a compilar estáticamente.
Para ello vamos a editar el archivo makefile donde podemos decirle a la variable DOSTATIC que sea true.
También podríamos decirle que utilice las librerías libc5 en vez de libc6 para que sea mas pequeño el ejecutable o directamente utilizar las nuevas librerías especialmente diseñadas para sistemas embeded uC-libc.
El archivo compilado final debe estar entre los 200 a 500k según con que librería lo compilemos y si es dinámico o estático.
Para comprobar esto utilizamos el comando ldd:
# ldd busybox
statically linked (ELF)
Compilando el kernel:
Acá viene el cuco de todo newbie, la hora de armar el kernel.
recuerden que queremos que sea lo mas pequeño posible así que vamos a sacar a diestra y siniestra todo tipo de soporte innecesario y sin módulos por supuesto.
La idea es que pueda ser booteado desde disquete con soporte vga y teclado.
También vamos a habilitar lo siguiente:
-RAM disk support
-Initial RAM disk (initrd)
-ROM file system support
Creando el Root file system:
Ahora vamos a crear la estructura de directorios y archivos básicos del sistema.
Creamos primero un directorio:
# mkdir minilinux
# cd minilinux
Creamos la estructura básica de directorios:
# mkdir dev etc etc/init.d bin proc mnt tmp var var/shm
# chmod 755 . dev etc etc/init.d bin proc mnt tmp var var/shm
Vamos a crear los devices
cd dev
# mknod tty c 5 0
# mknod console c 5 1
# chmod 666 tty console
Ahora creamos las vt’s (virtual terminals) para el display VGA
# mknod tty0 c 4 0
# chmod 666 tty0
Creamos el RAM disk
# mknod ram0 b 1 0
chmod 600 ram0
Creamos el null device, utilizado para descartar las salidas que no queremos
# mknod null c 1 3
# chmod 666 null
Ahora vamos al directorio minilinux/etc/init.d donde se alojan los scripts de inicio.
# cd ../etc/init.d
Con el editor que se les ocurra creen el archivo minilinux/etc/init.d/rcS que va a ser el que se va a ejecutar cada vez que arranque el sistema con el siguiente contenido:
#! bin/sh
mount -a #monta los file systems mencionados en /etc/fstab
hacemos el script ejecutable
# chmod 744 rcS
volvemos a etc
# cd ..
ahora vamos a crear el archivo minilinux/etc/fstab con el siguiente contenido
proc /proc proc defaults 0 0
none /var/shm shm defaults 0 0
Le cambiamos los derechos:
# chmod 644 fstab
Creamos el archivo minilinux/etc/inittab que le dice a bin/init, el programa de inicio del sistema, que proceso arrancar. Con el siguiente contenido
::sysinit:/etc/init.d/rcS
::askfirst:/bin/sh
En este caso corre primero el script /etc/init.d/rcS y luego levanta una shell
Cambiamos los derechos
# chmod 644 inittab
Nos falta copiar busybox al directorio minilinux/bin
# cp ruta_donde_compilamos/busybox /minilinux/bin
Ahora solamente nos queda armar todos los links a busybox
ar, basename, cat, chown, cp, rm, rmdir…..asi unos 107 comandos….)
Igual no se asusten ya que las versiones nuevas de busybox traen un script que arma todo lo expuesto anteriormente automáticamente. Solamente describí todos los pasos para que sepan como se hace a mano.
Generando la imagen de la ROM file system:
ya tenemos todo la estructura del sistema, nos queda armar el archivo que contiene todo el sistema para ello utilizamos el programa genromfs
# genromfs -d minilinux -f minifs
Este comando crea el ROM file system en el archivo minifs. Ahora lo vamos a comprimir:
# gzip -9 minifs
Armando el disquete:
Ya tenemos el kernel a medida y el archivo minifs.gz que contiene nuestro file system. Nos falta un bootloader, la eleccion correcta es syslinux.
Lo primero es formatear el disquette en FAT
# mformat /dev/fd0
luego cargamos el bootloader en nuestro disquete con el siguiente comando:
# syslinux /dev/fd0
Montamos el disquete y copiamos el kernel y el archivo de file system
mount -t msdos /dev/fd0 /mnt
cp minifs.gz /mnt
cp /usr/src/linux/arch/i386/boot/bzImage /mnt/linux
Creamos el archivo /mnt/syslinux.cfg con un editor que contenga lo siguiente:
TIMEOUT 20
DEFAULT linux
LABEL linux
KERNEL linux
APPEND root=/dev/ram0 initrd=minifs.gz
Esto le indica a syslinux que tiene que esperar 2 segundos y luego bootea el sistema por defecto.
Lo unico que resta es resetear la maquina con el diquete puesto y voila! deberiamos obtener al cabo de unos segundos y luego de los mensajes del kernel un prompt como para empezar a trabajar.
ESTE TEXTO SE PUBLICA BAJO LICENCIA CREATIVE COMMONS BY-NC-SA 2.5 AR.
Por lo tanto, usted es libre de: 1) Copiarlo, distribuirlo y exhibirlo. 2) Hacer obras derivadas. Bajo las siguientes condiciones: 1) Debe dar atribución mencionando el nombre del autor y del LUG Zona Norte. En caso de las notas que no llevan firma, mencionar sólo el nombre del LUG.
2) Usted no puede usar esta obra con fines comerciales. 3) Si usted altera, transforma, o crea sobre este texto, sólo podrá distribuir la obra derivada resultante bajo una licencia idéntica a ésta.
Más detalles y texto legal de la licencia en: http://creativecommons.org/licenses/by-nc-sa/2.5/ar

#1 by Sultanovich on 11/12/2006 - 23:00
muy bueno el articulo sechole, lastima que me falta algo de tiempo y muchos mas conocimientos pero queda agendado para un futuro cercano :).
Saludos.