Ahora ya se han expuesto las herramientas necesarias para poder generar un cdrom arrancable, a falta de un método ordenado. Éste consistirá en crear una partición de repuesto en el disco duro para hacer pruebas, antes de desechar inutilmente cdroms que no den el resultado esperado. Se podrá arrancar desde la partición correspondiente aunque con la peculiaridad de montarse como de sólo lectura (read only) con el fin que funcione como una memoria rom. Una vez testeada la prueba final, podremos pasar la partición a cdrom.
Todo ello se irá viendo en esta sección; el esquema sobre el que basaremos la metodología podría quedar así:
- conectar un disco duro y una grabadora de cdroms a la computadora que luego desearemos arrancar.
- particionar el disco de manera que dejemos al menos una partición (test) del tamaño del cdrom que vamos a usar (usualmente 700MB) y otra (principal) para realizar una instalación normal de Linux, desde donde generaremos la imagen arrancable y quemaremos el cdrom.
- se requerirán pues dos instalaciones de nuestro linux: una en la partición que contendrá lo que luego volcaremos al cdrom, y otra con soporte para quemar cdroms. Opcionalmente pueden copiarse en test los directorios que permitan arrancarlo, desde la instalación hecha en la partición principal; esto nos ahorrará hacer dos instalaciones.
- en principal montaremos test. En este ejemplo se usará la ruta absoluta /test, teniendo en cuenta que principal está montada en / .
- en el caso de que el kernel nos venga sin estas opciones (rara vez ocurre) arrancaremos test y re-compilaremos el kernel con soporte de isofs (el sistema de ficheros iso9660 es el estándar en cdroms) y soporte para cdrom, incluidos y NO como módulos.
- /tmp se montará en un ramdisk y apuntaremos /var hacia /tmp/var, teniendo en cuenta que estamos hablando de la partición montada en /test. Estos dos directorios son los que linux requiere como de lectura y escritura para mantener su coherencia. Configuraremos los ficheros necesarios para ajustarse a esta nueva situación del sistema.
- para el arranque del kernel hace falta echar mano de un disquete arrancable y configurarlo para utilizar el cdrom como dispositivo root (/). Ya se verá más detalladamente.
- finalmente quemaremos un cdrom con cdrecord.
CAMBIOS EN LA ESTRUCTURA DE DIRECTORIOS
Para empezar con los cambios en la partición test deberemos tener claro lo que hay que hacer, esto es, ser capaces de entender el proceso y no tanto de aplicar ciertas modificaciones a ciertos ficheros obviando lo que ello pueda significar. Este último método sin duda acortaría notablemente la duración del capítulo, no obstante y como Vd. querido lector ya sabrá, las estrucutras de directorios y nombres de los ficheros que contienen pueden sufrir variaciones entre distribuciones (y entre versiones de las mismas).
Suponiendo que se ha comprendido el funcionamiento de los ramdisk y que se tiene cierta soltura con lilo para arrancar sistemas linux, empezaremos a moldear los ficheros para que sean capaces de mantener funcionando nuestro equipo aun estando, o almenos en parte, en un dispositivo rom.
Quede claro pues que se modificará la estructura de archivos de la partición test para que pueda arrancarse con los permisos necesarios en una unidad de sólo lectura, como es un cdrom. Las rutas que se dan suponen que se está trabajando desde test. El esquema de las modificaciones que le aplicaremos es el siguiente:
- Apuntar /var a /tmp/var . El objetivo del enlace puede no existir aún, pero se generará en el arranque gracias a un script. De momento lo veremos como un enlace roto.
ln -s /tmp/var /var
/var será otro directorio en el que será necesario poder escribir. Se construye esta estructura -apuntándolo hacia /tmp/var- aunque evidentemente podríamos generar otro ramdisk y montar var en él. Esto son decisiones de diseño.
- Configurar el runlevel a 1. Bastará editar el fichero /etc/inittab y cambiar la linea
id:
N
:initdefault: donde N será seguramente 3 ó 5
por
id:1:initdefault:
Dando un repaso rápido a los runlevels, podemos verlos como diferentes niveles de arranque del linux en nuestro equipo. El modo 1 es el modo monousuario (ingl. single user mode), el modo 3 es el modo multiusuario completo con red (ingl. full multiuser with network) y el 5 es el modo multiusuario completo con red y gestor de escritorio (ingl. full multiuser with network and xdm). Hay 6 niveles pero en los arranques normales de linux se utilizan básicamente el 3 y el 5. Trasladar linux a runlevel 1 comportará que no se requiera login ni contraseña para ejecutar el shell.
¿Por qué es necesario trabajar con runlevel 1? Un sistema multiusuario necesita poder guardar información sobre los errores del servidor X-window de cada usuario que lo utilice, guardar información de los comandos de la consola y toda una retahíla de información que debe poder escribirse. En sistemas live, donde se depende de un dispositivo mucho más lento que un disco duro, sin memoria virtual (swap) y donde necesitamos la memoria primaria para poder cargar directorios para escritura, es mucho más cómodo trabajar en monousuario.
- Borrar (o comentar con # al inicio) en el archivo /etc/fstab cualquier referencia a dispositivos de memoria virtual swap. Estas lineas, en discos duros IDE, se muestran como algo parecido a:
/dev/hd<X> swap swap pri=42 0 0
El otro cambio que se efectuará en fstab es el dispositivo para montar / . En principio será la partición donde esté localizada test pero al trasladar los cambios al cdrom deberemos indicar aquí hda, hdb, hdc o hdd según donde tengamos conectado el lector. Esto sería, en un caso concreto, pasar de: /dev/hdb3 / reiserfs defaults 1 1
/dev/hdc / iso9660 defaults 1 1
Puede ser una buena idea escribir ambas líneas y comentar la segunda, de cara a recordar que más tarde deberemos pasar el comentario a la primera linea para poder arrancar correctamente. Puede observarse que el sistema de ficheros se adaptará al nuevo dispositivo rom, así que independientemente del formato de nuestra unidad en disco duro (ext2, ext3, xfs, reiserfs...) el cdrom se quemará con el estándar iso9660. Ya se ha advertido anteriormente que es importante tener soporte para él en el mismo kernel.
- Aumentar el tamaño de los ramdisks, añadiendo en el fichero lilo.conf
ramdisk = 35000
dentro de la entrada que se corresponda con el arranque de la partición test. No olvidemos ejecutar el comando lilo para actualizar los cambios.
Este parámetro solo tendrá efecto para el arranque de la partición desde disco duro, más tarde se detallará dónde debe incluirse esta linea para que tenga efecto en el arranque live.
- Enlazar mtab. Este fichero se actualiza cada vez que se monta o desmonta un dispositivo, por lo tanto debemos poder modificarlo aún estando en el lugar donde linux lo buscará (en /etc). ¿Cómo hacer esto? Convirtiendo mtab en un enlace simbólico hacia /proc/mounts, fichero al cual empezaremos actualizándole las fechas de acceso
touch /proc/mounts
rm -rf /etc/mtab
ln -s /proc/mounts /etc/mtab
En algunos scripts aparecen las lineas
# Clear mtab
>/etc/mtab
para reinicializar el fichero en cuestión. Si este cambio se aplica tras haber montado nuestros dispositivos en memoria, puede darse el caso de que nuestro equipo no los vea, algo que se traduce en una inconsistencia mediana o grave. Lo mejor será comentarlo (añadiendo # al inicio de la linea).
Es importante trabajar desde test para generar los enlaces, puesto que si creamos los enlaces con rutas desde principal (como /test/var o ./tmp/var) la partición test no los reconocería correctamente puesto que ella, al arrancar, tendrá /var montado en /tmp/var y no en ./tmp/var (partiendo de /etc o de /test).
- Convertir la unidad en acceso de sólo lectura es fácil puesto que en estos scripts de iniciación de remonta / para hacerla de lectura y escritura. Las lineas que se corresponden a esta operación deben ser algo parecido a
# Remount the root filesystem read-write.
state=`awk '/(^\/dev\/root| \/ )/ { print $4 }' /proc/mounts`
[ "$state" != "rw" ] && \
action $"Remounting root FS in read-write mode: " mount -n -o remount,rw /
que debería sustituirse por
# Remount the root filesystem read-write.
state=`awk '/(^\/dev\/root| \/ )/ { print $4 }' /proc/mounts`
[ "$state" != "rw" ] && \
action $"Remounting root FS in read-only mode: " mount -n -o remount,ro /
igualmente debería anularse cualquier referencia a memoria virtual (swap). Como puede apreciarse en el siguiente ejemplo, la linea se ha comentado para que no sea ejecutada.
# Start up swapping.
# action $"Activating swap partitions: " swapon -a -e
Por regla general en estos scripts no hay ninguna referencia más a dispositivo de lectura y escritura. No obstante estaría bien tomar paciencia y repasarlos de arriba a abajo. Generalmente estan muy bien comentados -en inglés- ahorrándonos muchos dolores de cabeza.
- Finalmente tendrá que generarse el ramdisk y su árbol de directorios para que pueda guardar todas las entradas en /tmp y /var que el sistema requiera7.21. Podemos editar /etc/rc.sysinit o cualquier script que venga con nuestra distribución y al que se invoque en el arranque.
Las siguientes lineas deberán incluirse almenos tras configurar el PATH, i.e. allá donde linux irá a buscar los ficheros binarios mkdir y mkfs (entre otros) necesarios apra crear directorios y sistemas de archivo, respectivamente). Esta linea puede aparecer como
# Set the path
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
Una buena forma de asegurarnos de no cambiar los permisos del ramdisk y mantener la coherencia de mtab es incluir estas lineas directamente a continuación de remontar / como sólo lectura.
- crearemos el dispositivo en memoria y le daremos formato
action "Making ram0 " /sbin/mkfs.ext3 /dev/ram0
action "Mounting ram0" mount /dev/ram0 /tmp -o defaults,rw
- crearemos el árbol de directorios
action "Making /tmp/etc" mkdir /tmp/etc
action "Making /tmp/var" mkdir /tmp/var
action "Making /tmp/var/log" mkdir -p /tmp/var/log
action "Making /tmp/var/run" mkdir -p /tmp/var/run
action "Making /tmp/var/lock" mkdir -p /tmp/var/lock
action "Making /var/lock/subsys" mkdir -p /var/lock/subsys
action "Making /tmp/var/lib" mkdir -p /tmp/var/lib
action "Making /tmp/var/spool" mkdir -p /tmp/var/spool
action "Making /tmp/var/spool/mqueue" mkdir -p /tmp/var/spool/mqueue
- cambiaremos los permisos para poder escribir en ellos
action "Chmod 777 /tmp " chmod 777 /tmp
action "Chmod +t /tmp" chmod +t /tmp
- haremos un nuevo dispositivo ramdisk y le copiaremos el contenido de /dev
echo "mkdir /tmp/dev" mkdir -p /tmp/dev
echo "Making ram1 " /sbin/mkfs.ext2 /dev/ram1
echo "Mounting ram1" mount /dev/ram1 /tmp/dev
echo "cp -a /dev/* /tmp/dev/" cp -a /dev/* /tmp/dev/ > /dev/null
echo "umounting /tmp/dev" umount /tmp/dev
echo "remounting /tmp/dev to /dev" mount /dev/ram1 /dev
Tras esto test debería arrancar sin mayores problemas. Es normal que se nos quede colgada en algunos de los muchos ensayos que vamos a hacer hasta llegar a este resultado. No obstante debe avanzarse siguiendo una lógica y no suponiendo que tenemos algo que no lo hace funcionar. Algunos scripts necesitarán llegar a cierta estructura de árbol (en /var o /tmp) y en caso de que no lo hayamos generado en el dispositivo en RAM nos devolverá un error. Simplemente añadiendo y/o modificando las líneas del punto b) para creación de directorios podremos arreglar esto.
¿Por qué no se ha hablado de /proc? Este directorio contiene información sobre lso procesos que corren en nuestro equipo, pero ya por defecto se monta en memoria. Por esta razón -y no por otra- no deberemos encargarnos de él.
ARRANCANDO UN KERNEL CON UNA IMAGEN DE DISQUETE
Para proceder con estos, los últimos pasos para obtener el cdrom, es mejor reiniciar el sistema y trabajar desde principal (siempre teniendo test en /test).
Para generar disquetes arrancables existen varios métodos. Quizá el más simple y efectivo sea obtenerlo directamente del cdrom de alguna distribución. Generalmente aparecen con nombres como boot.img o bootdisk y siempre tienen un tamaño de 1,4 mega-octetos. De forma alternativa podremos generarlo nosotros mismos.
- hacer una copia del kernel
cp /boot/vmlinuz-
version_del_kernel
/tmp/vmlinuz
- hacer la copia arrancable del cdrom en /dev/
dispositivo_cdrom
rdev /tmp/vmlinuz /dev/
dispositivo_cdrom
ramsize /tmp/vmlinuz 20000
- formatear un disquete y copiar el kernel
mkfs -t ext2 /dev/fd0
dd if=/tmp/vmlinuz of=/dev/fd0
En el caso de que se disponga de la imagen de un disquete arrancable, deberemos modificar ciertos parámetros. Para hacerlo deberemos montar esa imagen:
mount
fichero_imagen
directorio_de_montaje
-o loop -t vfat
En
directorio_de_montaje
debería aparecernos almenos: una imagen binaria del kernel de linux (vmlinuz), algunos ficheros binarios para los menús de pantalla y los ficheros que consideraremos importantes, ldlinux.sys y syslinux.cfg. Deberemos editar el segundo para personalizarlo a nuestro sistema. Básicamente deberá contener la etiqueta del arranque y el nombre de la imagen, por ejemplo:
default linux
label linux
kernel vmlinuz
root=/dev/<dispositivo_cdrom>
ramdisk=35000
Si estamos familiarizados con LiLO no nos será difícil configurar este fichero. La otra cosa importante es sustituir vmlinuz por la imagen que arranque test (y su fichero initrd en caso de que exista; ambos los encontraremos en /test/boot/). En el apéndice Salidas de comandos y ficheros podrás ver un caso concreto de este archivo7.22. Ahora desmontaremos la imagen.
umount
directorio_de_montaje
Y copiaremos esta imagen de disquete arrancable al directorio /test. El kernel embebido aquí será el que arrancará el sistema.
Un testeo interesante antes de quemar el cdrom es probar si la imagen de disquete que hemos creado funciona. La manera rápida y eficaz de hacerlo es copiar dicha imagen con el mismo comando dado para copiar el kernel aunque indicando el fichero adecuado a if, así dd if=bootdisk of=/dev/fd0 . Podemos arrancar la computadora y si este arranque parece funcionar (¡no tendrá sistema de ficheros!), probaremos con el cdrom.
Ahorrando una segunda instalación. Copia de contenidos
Una variante de este esquema podría darse cuando no hayamos cumplido un proceso de instalación en test. Tendremos que tener en cuenta que podremos aprovechar la mayor parte de los directorios de la partición principal (siempre y cuanto quepan en el directorio /test). En el árbol de directorios, excepto /usr, el contenido de los demás directorios no será crítico. En /test podremos disponer la estructura copiando los directorios desde principal y arreglando los ficheros necesarios en /etc .
Para generar los directorios en test, por ahora vacía, podríamos ejecutar:
cd /test
mkdir root
mkdir mnt
mkdir proc
mkdir tmp
mkdir home
mkdir misc
mkdir opt
mkdir dev
E iniciamos la copia de contenidos con rsync. Alternativamente podríamos usar el comando cp -a.
rsync -a /dev/* dev
mkdir lib
rsync -a /lib/* lib
mkdir bin
rsync -a /bin/* bin
mkdir sbin
rsync -a /sbin/* sbin
mkdir usr
mkdir etc
rsync -a /etc/* etc
mkdir boot
rsync -a /boot/* boot
Antes de empezar con el proceso de quemado es necesario recordar que hay que modificar el fichero /test/etc/fstab para indicarle a linux que el dispositivo root ahora no será la partición test sino el cdrom (con iso9660).
Para disponer en un cdrom todos los contenidos que hasta ahora hemos modificado seguiremos los siguientes pasos:
- crear la imagen iso9660 llamada boot.iso (situados en el directorio donde queramos generarla)
mkisofs -R -b boot.img -c boot.catalog -o boot.iso /test
- verificar la imagen iso, montándola en algun directorio
mount boot.iso
directorio_de_montaje
-o loop -t iso9660
- quemar el CD
cdrecord -v speed=
velocidad
dev=
ruta_del_grabador
boot.iso
- verificar el arranque desde cdrom, re-arrancando la computadora.
Puede ser interesante, desde el punto de vista práctico, mostrar una pantalla antes de empezar con el arranque del kernel, para poder elegir las opciones con las que va a hacerlo. Esto es modo gráfico, tamaño de los ramdisks, etc...
Por el momento el espacio disponible en un disquete no nos permite poder embeber en él varios kernels de tamaño tradicional. No obstante si se trabaja con sistemas con pocos requerimientos se podrán arrancar varias imágenes vmlinuz. El fichero syslinux.cfg se maneja como el lilo.conf así que no debería darnos más problemas. En el apéndice Salidas de comandos y ficheros se adjunta un ejemplo.
Para mostrar un menú podemos añadir, a la cabecera de syslinux.cfg, la linea
display boot.msg
donde boot.msg será la pantalla a mostrar. Este fichero podemos editarlo con un editor de texto llano, aunque contiene algunos bytes en binario que deberemos respetar. Igualmente podremos llamar otros menús a partir de éste, con las teclas de función. Estas configuraciones también irán a la cabecera de syslinux.cfg7.23.
Las posibilidades que brinda este cargador pueden embellecerse usando los 16 colores que cualquier targeta VGA soporta. A continuación se da un ejemplo de un menú que mostraría por pantalla, en cada color, el número hexadecimal que lo codifica.
^L
Ejemplo de colores para el mensaje de arranque desde un disquete botable:^O07
^O01 azul claro=1 ^O07
^O02 verde=2 ^O07
^O03 azul claro=3 ^O07
^O04 rojo oscuro=4 ^O07
^O05 purpura=5 ^O07
^O06 marron=6 ^O07
^O07 gris=7 ^O07
^O08 verde oscuro=8 ^O07
^O09 azul=9 ^O07
^O0a verde claro=A ^O07
^O0b azul claro=B ^O07
^O0c rojo=C ^O07
^O0d lila=D ^O07
^O0e amarillo=E ^O07
^O0f negrita=F ^O07
La estructura de estos ficheros es:
^L
limpia la pantalla. Es binario así que algun editor puede mostrarlo distinto a como aquí se muestra (con emacs). Para asegurar que se está tomando el carácter correcto lo mejor es hacerse con un fichero ya existente en cualquier liveCd y copiarlo.
- los colores se codifican con la secuencia
^O0x
donde x es un dígito hexadecimal (del 1 al F); y los saltos de linea son ^O07
El carácter con el que empiezan los código hexadecimales no es el acento circunflejo, así que si probamos de escribir el texto anterior tal cual no funcionará. Como se ha descrito, lo mejor es tomar ficheros ya existentes y copiar dichos códigos.
Para terminar con este apartado cabe decir que SuSE no ha reparado en esfuerzos hasta llegar a conseguir mostrar una inmejorable imagen de gecko (el camaleón verde que les sirve de logotipo) en nuestro sistema. Su gfxboot permite dispone las opciones como un menú a todo color. Para más detalles mejor consultar su syslinux.cfg .