Siempre que instalamos GNU/Linux en un equipo o utilizamos un disco de rescate lo hacemos casi sin pensar en lo que en realidad sucede, los datos que se almacenan en la RAM, o dónde están los binarios que utilizamos. Las cosas cambian cuando no tenemos un disco de arranque listo para usar, o peor aún, cuando no es posible utilizarlo por la insuficiencia de memoria del hardware a nuestra disposición, como es el caso con sistemas muy antiguos o pequeños.

Introducción

Al poco tiempo de conseguir una notebook realmente vieja y pensar en instalarle GNU/Linux, me di cuenta de que no iba a ser una tarea tan sencilla como la de instalar en cualquier equipo de escritorio, o inclusive en cualquier otro equipo portátil con mejores características. Paralelamente, recibiendo consultas sobre cómo armar discos de arranque Linux, decidí escribir esta breve descripcion de la inicialización de un sistema Linux, en relación con mi experiencia de instalar el sistema en un equipo tan paqueño. Si están interesados en conocer los pormenores del proceso de inicio del sistema, en condiciones normales, lo mejor será que se refieran al didáctico artículo de MaxDrake, titulado El proceso de inicializacion de GNU/Linux, publicado en este mismo sitio.

El caso en particular

El equipo portátil al que refiero en la nota, consta de las siguientes características: (no vale reirse :)

Texas Instruments TravelMate 3000 Procesador 386, sin coprocesador matemático. (2.74 BogoMIPS, snif!) 4Mb de RAM, expandibles a 6Mb(!). Disco Rigido Conner 40Mb Diskettera 3.5 Puertos PS/2, Serie 9600, Paralelo SPP, y VGA de salida. Conectores Propietarios para un modem interno y futuras actualizaciones (?) PCMCIA: No

Consideraciones generales

El fundamental problema es la carencia de RAM; y el mismo problema puede presentarse incluso en algun vetusto equipo de escritorio que intentemos convertir al GNUismo.

En primera instancia se puede pensar en una minidistro, o en los discos de Debian o Slackware por ejemplo; pero en todos ellos (o por lo menos, en los que probé), se da por sentado el hecho de que el sistema cuenta con la RAM suficiente como para armar un disco en ella y crear allí un sistema de archivos funcional. Como éste no es el caso, deberemos crear un sistema de archivos funcional (Kernel y sistema de archivos raíz con utilidades mínimas) en uno o varios diskettes, dejando la poca RAM disponible libre para ejecutar nuestras aplicaciones. Una salvedad es la minidistribución Small Linux, que no precisa la RAM, pero no es tan cómoda como para utilizarla a diario, al menos para mi gusto.

Arrancando

Bien sea de diskettes, CD-ROMs, o discos rígidos, cuando el sistema se inicia deberá ser capaz de encontrarse con una de estas posibilidades:

  • Una copia de LILO, u otro gestor de arranque, que sepa enviar al sistema a una imagen del kernel, e indicar además -entre otras cosas-, dónde se encuentra el sistema de archivos, la cantidad de RAM que se puede usar para crear discos, etc.

  • Una imagen del kernel, que pueda por sí misma, saber lo que lilo habitualmente le indica.

    Para el caso de nuestros diskettes de inicio, podemos crearlos con o sin LILO, y ademas es posible:

  • Crear un sólo diskette, que contenga el arranque (Kernel o Kernel + LILO), y además una imagen comprimida del sistema de archivos.

  • Crear dos diskettes: uno con el arranque, y otro con un sistema de archivos totalmente funcional,comprimido o sin comprimir.

    Como ya dijéramos, ante la carencia de RAM no será posible utilizar imágenes comprimidas, y aunque el espacio para las aplicaciones se reduzca mucho, es posible alcanzar una funcionalidad aceptable.

    El kernel

    Podemos compilar alguna versión que incluya el soporte que necesitemos, o utilizar alguna otra ya compilada. En mi caso particular, elegí un núcleo que se incluye en la minidistribcion NucLinux; es un Kernel 2.2.18 con soporte monolítico para minixfs, vfat y conexiones de red, y sólo ocupa 400 Kb. Las explicaciones de aquí en más debieran funcionar con Kernels más viejos que aquel, pero desconozco de momento las particularidades de los nuevos nueclos 2.4.x. Cabe resaltar aquí, que si deciden compilar un kernel para el sistema en cuestión, será conveniente incluir sólo el soporte necesario. Para mi caso en especial, no es necesario, por ejemplo, el soporte USB, SCSI, PCI, Ethernet, ni PCMCIA. Esto ahorrará unos buenos Kb de RAM.

    El sistema de archivos

    Para que Linux pueda arrancar correctamente, precisaremos, como mínimo:

    Un directorio /dev, conteniendo los dispositivos mínimos para funcionar: fdx, hdx y familia, ttyx para las terminales, cuax o ttySx para puertos serie, lpx para el puerto paralelo, psaux para PS/2, ram, ramx para discos virtuales, loopx para montar imagenes como si fueran discos, y los dispositivos especiales null, zero y random. Esto puede hacerse de dos maneras: copiando los dispostivos ya existentes en su propia distribución, y borrando los que no necesiten (porque consumen inodos del sistema de archivos), o bien creándolos uno a uno con el comando mknod; por ejemplo, para crear el dispositivo hda1, podria ser:

    mknod hda1 b 3 1

    Un directorio /bin, con los binarios básicos: bash, ls, cp, etc. Aquí puede ser útil apelar a una herramienta llamada Busybox, especialmente pensada para sistemas embebidos o escasos de disco. Busybox, puede reemplazar a varios comandos importantes, tratándose sólo de un binario. Bastará con crearle enlaces simbólicos con nombres como df, ln, pwd, chmod o which. Para conocer todas las herramientas que pueden reemplazarse con Busybox, consulten su documentación.

    El directorio /etc, donde estarán, fundamentalmente, los scripts de inicio del sistema, además de otros importantes como el archivo de claves, grupos, termcap, con informacion de las terminales, fstab, mtab o profile, e incluso XF86Config, en caso de que decidan instalar X. La lista completa de archivos que se debe incluir, está en el documento Linux BootDisk-HOWTO.

    El directorio /lib, con las librerías necesarias para correr nuestras aplicaciones. En ocasiones como esta, se percibe el valor de la compilación dinámica, porque el ahorro de espacio en disco, llega a ser vital. Ejemplos de librerías que van en /lib: libc.so.5, ld-linux.so, libdl.so, etc. Para saber acerca de las librerías que precisa un binario para funcionar, pueden utilizar el comando ldd. En ocasiones, se prefiere utilizar binarios y librerias mas bien desactualizados, porque suelen ocupar menos espacio en disco, pero tengan cuidado con las incompatibilidades que podrán encontrar en el camino. Un ejemplo claro, son las diferencias en el soporte del sistema de archivos ext2 con nucleos de las series 2.0.x, y libc5.

    También habrá que crear directorios vacíos, como /proc, para el sistema proc, /tmp para que los procesos puedan almacenar datos temporalmente, y un directorio /sbin, que contendra los binarios vitales del sistema, como init, mingetty o alguno similar. Aunque no haya quedado muy ordenado, en mi disco simplemente he creado un enlace /sbin que apunta a /bin, dejando de lado ciertas consideraciones de seguridad, dado el carácter del hardware sobre el que se operará.

    Además, podran crear un directorio /home, para los usuarios, /var para las colas y registros (logs), y /mnt, por si precisan montar otros sistemas de archivos allí.

    Si el sistema de arranque que construyen, servirá para tratar las particiones del disco rígido, crear sistemas de archivo, o cosas similares, deberán incluir en su directorio de binarios, utilidades como fdisk, fdformat, mkfs., fsck., dd, cpio, mknod, y rdev. El modo lowmem de MuLinux puede ayudar también.

    En cuanto a los binarios y librerías, estos suelen compilarse, con datos extras que no son necesarios para su funcionamento, sino solo para su depuración. Dichos datos, ocupan espacio importante en el disco, y pueden quitarse del binario o la libreria (para los puristas, donde dice librería deben leer biblioteca), usando objcopy --strip-all archivo, u objcopy --strip-debug archivo. Si van a stripear bibliotecas, recuerden utilizar --debug-only, porque de lo contrario no funcionarán correctamente.

    Finalmente, si precisan utilizar diskettes formateados con capacidades no estándar, deberán incluir además en el directorio /dev, las entradas correspondientes; por ejemplo, fd0H1772 para discos de 3.5 formateados a 1.77 Mb. Aunque es posible dar formato a los discos de 3.5, por cerca de los 2 Mb, es preferible no pasarse de los 1.77Mb, dado que es la más aceptada por la mayoría de las disqueteras (no todas).

    Creando los diskettes

    Con el kernel y el sistema de archivos en mano, procederemos a crear los discos de arranque. Es preciso cerciorarse de que no contengan sectores defectuosos, y eso lo averiguaremos con fdformat. Comenzaremos creando los más fáciles: un diskette con boot y otro con root, sin comprimir. Este par de diskettes, es el que utilicé para bootear sobre el sistema descripto anteriormente.

    Transferiremos la imagen del kernel, al primer diskette:

    dd if=linux of=/dev/fd0 bs=1k

    Le indicaremos de donde arrancar:

    rdev /dev/fd0 /dev/fd0

    Fijaremos el ROOT FLAG en lecto-escritura:

    rdev -R /dev/fd0 0

    o

    rootflags /dev/fd0 0

    Y por último declararemos el valor de la palabra RAMDISK:

    rdev -r /dev/fd0 32768

    o

    ramsize /dev/fd0 32768

    Nos detendremos en los últimos comandos que hemos utilizado. Incómodos de usar desde sus orígenes, rdev, o sus alias (en realidad enlaces) ramsize, rootflags, swapdev o vidmode, son herramientas que permiten mostrar o modificar ciertos parámetros sobre una copia del Kernel en particular. Esos parámetros se almacenan en un sector determinado de la imagen de Kernel. El parametro que pasemos usando rootflags, puede ser 1 para solo lectura, o 0 para lecto-escritura, como en el ejemplo. En el caso del primer comando, creo que queda bastante claro, y es simplemente indicar donde esta el sistema de archivos para arrancar. En cuanto al valor de ramsize, discutiremos más profundamente; Esta palabra, esta compuesta de varios datos, a saber:

    bit Significado: 0-10 Desplazamiento al inicio de la imagen, en bloques de 1024 bytes. 11-13 Sin usar. 14 Bandera que indica que se va a cargar la imagen de disco, en memoria. 15 Bandera que indica preguntar antes de cargar el sistema de archivos.

    Deberemos calcular cuidadosamente el numero, para que surta el efecto esperado sobre la imágen. En el ejemplo, se puede deducir entonces, que las banderas de los bists 0 al 14 estan en 0 y se ha puesto a 1 sólo la 15; el desplazamiento es 0 (el sistema de archivos comienza en el bloque 0 del segundo diskette) y el sistema deberá pedir que se cambien los discos antes de intentar la carga del sistema de archivos raiz desde el disco 2. Como 2 a la 15 es 32768, es el numero que hemos utilizado como parámetro para rdev -r, puesto que no habia otras partes de la palabra puestas en 1. Si precisáramos indicar un desplazamiento en particular, deberíamos sumar también el valor correspondiente. La palabra, será indicada siempre en sistema de numeración decimal, y no teman hacer expermientos con ella, a menos que se trate de una imagen en su disco rigido; esto puede inutilizar su instalación, aunque sea instantaneamente. En un ejemplo de más abajo, pueden ver como utilizamos la primera parte de la palabra ramdisk, para indicar al Kernel cuantos bloques debe saltear para encontrar una imágen utilizable como root filesystem.

    En cuanto al segundo diskette, la creacion será de lo más sencilla. Con la estructura de root que hemos creado en la sección anterior, simplemente daremos formato a la media del diskette con fdformat, crearemos un sistema de archivos soportado por el Kernel (ext2 o minix, por ejemplo), y transferiremos los directorios imprescindibles, de los que ya discutieramos líneas arriba.

    Cabe notar que para copiar archivos especiales, o directorios con su contenido, usaremos cp con los parametros -vdpR: v para mostrar mensajes (verbosity), d para preservar los links, p para preservar los atributos de los archivos, y R para funcionar de modo recursivo.

    [PAGEBREAK]

    Arranque con Sistema de archivos comprimido

    Para el caso de los root filesystems sin comprimir, puede ser desesperante la carencia de espacio en disco, puesto que en el mejor de los casos, contaremos con 1.77 Mb para completar con librerías, configuración y binarios. Si optamos por sistemas comprimidos, podremos contar con 4Mb o mas de tan preciado espacio, lo cual es mucho más cómodo. Es posible renunciar a bash, y optar por algun otro shell más minimalista, que ocupe menos espacio en disco, como ash, kiss o smash. Puede que no tengamos el autocompletado u otras características, pero los 250 Kb que ocupa bash en disco como promedio pueden ser realmente utiles para otra cosa, sin contar la RAM que nos ahorraremos.

    Si el equipo en cuestión cuenta con la RAM suficiente, será posible crear sistemas de archivos comprimidos, mucho más generosos al momento de incluir utilidades. Teóricamente, con 6 u 8 Mb de RAM, es posible crear sistemas de archivos virtuales ocupando de 4 Mb a 6 Mb, y dejando el resto para el Kernel y las aplicaciones.

    De manera similar al ejemplo anterior, ya deberan tener lista la estructura del sistema de archivos raiz, en algún lugar en su disco. Deberán crear una imágen que contenga ese sistema de archivos, para luego comprimirla:

    dd if=/dev/zero of=archivoimagen bs=1k count=nnn

    Donde nnn es el numero de bloques de 1024 bytes que se van a utilizar. Utilizando 4096, por ejemplo, crearemos una imágen vacía de 4 Megas. Noten el dispositivo de entrada que usa el comando dd en la declaracion de mas arriba: /dev/zero. Se trata de un dispositivo, que solo devuelve ceros, y es útil por ejemplo, para realizar benchmarks de transferencia, o en casos como éste, para rellenar un archivo con ceros. En el caso de nuestra imágen, es importante llenarla con ceros porque luego será comprimida, y si en lugar de ceros hubiese basura, la compresión perdería eficacia. Si necesitan borrar algo que ya transfirieron a la imágen, recuerden que los ceros no volverán a su lugar, asi que será conveniente crearla de nuevo, y volver a emplazar los contenidos, con las modificaciones realizadas.

    Creado el archivo, habra que armar en él un sistema de archivos ext2, o minix, como prefieran:

    mke2fs -m 0 -N 1000 archivoimagen

    El primer parámetro sirve basicamente para ahorrar espacio, mientras que el segundo, indica la cantidad de inodos que se usarán. El número que indico es suficiente, y puede ser aún menor, pero deben tener en cuenta que los dispositivos de /dev, pueden comerse nuestros inodos muy rápidamente. Es posible que mkfs proteste antes de crear el fs, porque el parametro archivoimagen no es un archivo de bloques. No hay problema, contestad afirmativamente.

    Esta imágen, se puede montar con el comando:

    mount -t ext2 -o loop archivoimagen /mnt/prueba

    Recuerden que deben tener los dispositivos especiales tipo loop para que las cosas funcionen así, pero no se preocupen, en toda distro moderna ya están incluídos.

    Una vez que tenemos dentro del archivo imágen todo lo que necesitamos, pasaremos a comprimirla, para luego trasferirla al diskette root:

    dd if=archivoimagen bs=1024 | gzip -v9 > archivoimagen.gz

    Si deciden crear un solo diskette, que contenga la imagen comprimida del sistema de archivos, y el kernel, pueden armarlo como sigue:

    Transferir el kernel, como anteriormente, y recordar esta vez la informacion que devuelve dd:

    443+1 records in 443+1 records out

    Para mi caso, el número indica que los datos del kernel ocuparon 443 bloques completos, además de un bloque adicional, ocupado parcialmente. Solo hay que recordar 444. Si hubiera sido 443+0, el número a recordar sería 443. Este número, indica cuantos bloques del diskette han sido usados por el kernel. En consecuencia, nuestra imagen del root file system, deberá comenzar a grabarse inmediatamente a continuacion:

    dd if=archivoimagen of=/dev/fd0 bs=1k seek=444

    El ultimo parámetro de dd (seek=), indica cuántos bloques saltar antes de empezar a transferir la información.

    Luego, deberemos indicar al kernel, que el sistema de archivos se encuentra en el mismo disco:

    rdev /dev/fd0 /dev/fd0 rdev -R /dev/fd0 0 rdev -r /dev/fd0 16828

    Noten que el ultimo numero (16828), refleja la suma del flag del bit 14 (explicado más arriba), con el numero de bloque en que comienza la imagen (444+16384). Como se trata del mismo disquette, la bandera del bit 15 se deja en 0, pero bien podria tratarse de otro disco conteniendo el sistema de archivos, en cuyo caso el offset iria a 0 y las banderas 14 y 15, en 1.

    La instalación en el disco rígido

    Una vez creados mis disquetes de sistema, a 1.77 Mb, procedí a crear las particiones: 6Mb de intercambio, y el resto para /. Copiados los directorios para recrear el sistema de archivos en el disco rígido, cambié nuevamente los parámetros del diskette de arranque, para indicarle que esta vez el sistema de archivos raiz, estaba en el disco rígido, permitiéndome utilizar la diskettera con otros fines:

    rdev /dev/fd0 /dev/hda1 rdev -R /dev/fd0 0 rdev -r /dev/fd0 16384

    Contando con la diskettera, pude copiar al disco rígido una imágen del Kernel, una copia de lilo, vi y otras utilidades, creando luego un archivo de configuración para lilo:

    boot=/dev/hda1 install=/boot/boot.b map=/boot/map read-write backup=/dev/null compact image=/boot/linux root=/dev/hda1

    Hecho esto, se puede invocar luego a LILO, para que se grabe en el MBR del disco:

    /sbin/lilo -v -C /etc/lilo.conf

    Quedando instalado el sistema, en el disco rígido, y con espacio de intercambio.

    Mas documentacion y otras herramientas

    A continuacion, detallo un listado de links que pueden serles utiles para completar la informacion que propongo en la presente:

  • Boot-Disk HOWTO, para encontrar todo lo explicado sobre inicio y creacion de diskettes, en detalle.
  • 4mb-laptops HOWTO, donde se plantea la problemática de los 4 Mb de RAM, y las posibles maneras de resolverla.
  • Laptops-HOWTO, para encontrar experiencia previa, y ayuda sobre la compatibilidad del hardware, aunque puede ser algo tedioso de leer

    Minidistribuciones:

  • Small Linux
  • LIAP
  • NucLinux
  • MuLinux
  • Trinux
  • Los discos de rescate de Debian

    Herramientas de bajo peso:

    Scripts para construccion de discos:

    • mkbootdisk (de RedHat) y mkfloppy (de NucLinux)

    Paginas de manuales de: cpio, dd, fdformat, mkfs.*, fsck, mount, rdev, mknod, file, ldd, objcopy, fdisk y lilo.

    Conclusión

    Verán que armar un diskette de arranque en Linux no es tan simple como uno pudiera imaginarse en base a la experiencia adquirida en otros sistemas, pero la experiencia permite conocer más a fondo el modo de funcionamiento de nuestro OS al momento de arrancar, comprender comandos que no se utilizan tan a menudo y depender un poco menos de las herramientas que hacen las cosas por nosotros. Con este conocimiento bajo el brazo podemos armar diskettes de rescate, instalación, e incluso CDs de recuperación de sistema, booteables y que restauren una estructura de disco, por ejemplo.

    En mi caso, una vez transferido el sistema al disco rigido, he instalado luego soporte PLIP y SLIP, protocolos de red y utilidades, e inclusive X Window, en una versión especial para sistemas minúsculos: TinyX, cuyos fuentes se incluyen con el codigo de XFree86 4.x. La selección concienzuda de apliaciones, permite instalar Linux en cualquier cosa, incluyendo Laptops, Notebooks, HandHelds, PDAs, o sistemas embebidos. Si necesitan instalar GNU/Linux en un sistema aun más viejo (8086 o 286), deben referirse a proyectos como ELKs, pero noten cómo es posible instalarlo en un hardware aun más viejo que el mismo SO! (Linux data del 91, y los procesadores 386 de finales de los 80s). Las fronteras solo las impone la voluntad. Buena suerte.

    ©2001 Ariel R. Graneros

  • Publicidad

    © 2006 Planeta Linux Argentina. La fuente de recursos Linux desde 1999. Desarrollado por VivaServer.