CD Arrancable Fácil de tu LFS

TÍTULO:			CD Arrancable Fácil de tu LFS
VERSIÓN LFS:	3.3
AUTOR:			Thomas Foecking <thomas@foecking.de>
				Christian Hesse <mail@earthworm.de>
TRADUCTOR:	Proyecto LFS-ES

SINOPSIS:
	Cómo crear un CD Arrancable fácil de tu sistema LFS.

RECETA:
Versión 0.2c
27/04/2002

Índice
--------

    1. ¿Qué necesitas y cuál es la idea?
    2. Configura y compila el núcleo (kernel)
    3. Mueve /dev /var /tmp /root /home a /falso/necesita_escritura
    4. Crea enlaces simbólicos /... -> /falso/necesita_escritura/...
    5. Crea un guión de arranque que monte el disco virtual en memoria (ramdisk)
    6. Instala el Cargador de Arranque isolinux
    7. Crea el disco virtual en memoria (ramdisk) inicial
    8. Tuesta el CD Arrancable
    9. Reinicia y disfruta


1. ¿Qué necesitas y cuál es la idea?
   ----------------------------------

	¿Qué necesitas?
	- El sistema LFS que quieres tostar en CD
	- Otro sistema linux/unix para crear alguna cosa y tostar el CD
	- El CD-R(W) para tostar tu sistema LFS y la imagen de arranque en CD
	- 1 CD-R + 1 CD-RW es muy recomendable para ahorrar dinero
	- sofware adicional:
syslinux: (contiene isolinux para arrancar el núcleo del LFS en CD)
http://freshmeat.net/redir/syslinux/10177/url_bz2/syslinux-1.67.tar.bz2

isoinfo: (opcional para detectar el CD LFS sin montarlo)
http://www-tet.ee.tu-berlin.de/solyga/linux/isoinfo-0.03.01.tar.gz

	Antes de nada necesitas un LFS ejecutándose, que quieras tostar en
	CD. Puede que quieras tener un CD LFS para crear nuevos sistemas en
	otras computadoras. Sean cual fuesen tus ideas, primero tendrás que
	crear este sistema especial en tu partición LFS.
	(Por ejemplo, he creado un sistema LFS con xfree86 y windowmaker;
	ahora puedo arrancar desde el CD y crear un nuevo sistema LFS sin
	olvidarme de xfree86 ni de windowmaker)

	¿Cuál es la idea?
	- Crear el núcleo con soporte para disco virtual en memoria (ramdisk) e initrd
	- Mueve /dev /var /tmp /root /home a /falso/necesita_escritura
	- Haz los enlaces simbólicos
		/dev  -> /falso/necesita_escritura/dev
		/var  -> /falso/necesita_escritura/var
		/...   -> /falso/necesita_escritura/...
	- Monta /dev/ram0 en /falso/ramdisk
	- Copia /falso/necesita_escritura/* a /falso/ramdisk/
	- Monta de nuevo /dev/ram0 en /falso/necesita_escritura

	Tendremos acceso de lectura-escritura en /dev /var /tmp /root /home
	porque apuntan a /falso/necesita_escritura el cual es el disco virtual en 
	memoria (ramdisk)

	Eres capaz de hacer la mayoría de las cosas desde los otros sistemas
	linux/unix ajustando LFS a tu punto de montaje de LFS. LFS=/path/to/lfs
	Por ejemplo:

LFS=/mnt/lfs

	¡¡No te olvides de ajustar de nuevo tu LFS cuando vaya a reiniciar!!


2. Configura y compila el núcleo
   -----------------------------

	Arranca tu sistema LFS o chroot en él.

--- opcional ---

	Estamos justo aquí en nuestra primera instalación de isoinfo que usarás más 
	tarde. Asumo que el paquete isoinfo-0.03.01.tar.gz está emplazado en /usr/src.

	¡Salta este paso si ya tienes instalado cdrtools! Estas cdrtools también
	contienen un programa llamado isoinfo que usaremos luego.

cd /usr/src
zcat isoinfo-0.03.01.tar.gz | tar x
cd isoinfo

./configure
sed "s/\/usr\/local\//\/usr\//g" Makefile > Makefile.new
mv Makefile.new Makefile
make

make install

--- fin de opcional ---


	Bien, configuremos ahora tu núcleo:

cd /usr/src/linux
make mrproper && make menuconfig

	¡Necesitas soporte para el disco virtual en memoria (ramdisk)!
		"Block devices  --->" 
			"<*> RAM disk support"
			"(4096)   Default RAM disk size"
			"[*]   Initial RAM disk (initrd) support"

	¡Necesitas soporte para el sistema de ficheros ISO 9660 CDROM!
		"File systems  --->"
			"<*> ISO 9660 CDROM file system support"

	Deberías pensar también en construir algunos controladores en tu
	núcleo o como módulos, lo cual sería mucho mejor.

	Si quieres ser capaz de arrancar el CD en muchos PCs con distintas
	CPUs (por ejemplo 486, Pentium, PII, PIII, Athlon) tienes que com-
	pilar tu núcleo para 486 (entonces se ejecuta en >= 486).
		"Processor type and features  --->"
			"(486) Processor Family"

	Guarda la configuración y compila tu núcleo:

make dep && make bzImage && make modules && make modules_install

	Entonces copia el nuevo núcleo construido a /boot:

cp arch/i386/boot/bzImage /boot/lfskernel && cp System.map /boot/

	Ejecuta Lilo (o actualiza el cargador de arranque que utilices):

/sbin/lilo

	Intenta arrancar el nuevo núcleo para probar el soporte del
	disco virtual en memoria (ramdisk):
	Si usas devfs debes cambiar: dev_ram=/dev/rd/0


dev_ram=/dev/ram0
mke2fs -m 0 $dev_ram

	Si esto falla con
	> The device apparently does not exist;
	> did you specify it correctly?
	tú no tienes soporte de disco virtual en memoria en tu núcleo.
	Deberías leer este capítulo otra vez ;-)

	Si no es así, ¡has hecho muy bien tu trabajo!

	Comprueba el tamaño de tu disco virtual en memoria montándolo en 
	/mnt y haciendo un  "df -h"

mount $dev_ram /mnt
df -h

	Ahora puedes arrancar tu otro sistema linux/unix ...


3. Mueve /dev /var /tmp /root /home a /falso/necesita_escritura
   ------------------------------------------------------------

	Movemos todo el conjunto con permisos de escritura a /falso/necesita_escritura.

	Primero hemos de crear este directorio
	y el punto de montaje para el disco virtual en memoria (ramdisk):

mkdir -p $LFS/falso/{necesita_escritura,ramdisk}

	Entonces podemos moverlo allí:

cd $LFS/
mv dev/ var/ tmp/ root/ home/ falso/necesita_escritura/


4. Creando enlaces simbólicos /... -> /falso/necesita_escritura/...
   ----------------------------------------------------------------

	Hemos movido /dev /var /tmp /root /home a /falso/necesita_escritura.
	Ahora debemos ajustar los enlaces simbólicos para que todo
	parezca estar como antes.

cd $LFS/
ln -s falso/necesita_escritura/dev dev
ln -s falso/necesita_escritura/var var
ln -s falso/necesita_escritura/tmp tmp
ln -s falso/necesita_escritura/root root
ln -s falso/necesita_escritura/home home

	"ls -l" dice:
	 dev  -> falso/necesita_escritura/dev
	 home -> falso/necesita_escritura/home
	 root -> falso/necesita_escritura/root
	 tmp  -> falso/necesita_escritura/tmp
	 var  -> falso/necesita_escritura/var

	Si también quieres ser capaz de cambiar los archivos de /etc en tu CD de
	arranque, debes repetir el mismo procedimiento para /etc.

cd $LFS/
mv etc/ falso/necesita_escritura/
ln -s falso/necesita_escritura/etc etc


5. Crear el guión de arranque que monte el disco virtual en memoria (ramdisk)
   --------------------------------------------------------------------------

	Bien,tenemos /dev /var /tmp /root /home enlazado a
	/falso/necesita_escritura el cual al principio es de sólo-lectura.
	Para ser capaces de registrarnos (y ejecutar servicios en los niveles de
	ejecución (runlevels) x los cuales necesitan permisos de escritura para
	/dev /var /tmp /root o /home) debemos llamar a un guión desde nuestro di-
	rectorio /etc/rc.d/init.d/ que cree un disco virtual en memoria para 
	/falso/necesita_escritura con permiso de escritura.

	El siguiente guión crea un disco virtual en memoria en /falso/ramdisk y copiará
	todo de /falso/necesita_escritura a /falso/ramdisk.
	Entonces monta de nuevo el disco virtual en memoria a /falso/necesita_escritura.

cat > $LFS/etc/rc.d/init.d/create_ramdisk << "EOF"
#!/bin/sh

dev_ram=/dev/ram0
dir_ramdisk=/falso/ramdisk
dir_needwrite=/falso/necesita_escritura

source /etc/rc.d/init.d/functions

case "$1" in
        start)
                echo -n "Creando ext2fs en $dev_ram ...              "
                /sbin/mke2fs -m 0 -i 1024 -q $dev_ram > /dev/null 2>&1
                evaluate_retval
                sleep 1
                echo -n "Montando el disco virtual en memoria en $dir_ramdisk ...         "
                mount -n $dev_ram $dir_ramdisk
                evaluate_retval
                sleep 1
                echo -n "Copiando archivos al disco virtual en memoria ...                 "
                cp -dpR $dir_needwrite/* $dir_ramdisk > /dev/null 2>&1
                evaluate_retval
                sleep 1
                echo -n "Montando de nuevo el disco virtual en memoria en $dir_needwrite ...        "
                umount -n $dir_ramdisk > /dev/null 2>&1
                sleep 1
                mount -n $dev_ram $dir_needwrite
                sleep 1
                ;;
        *)
                echo "Uso: $0 {start}"
                exit 1
                ;;
esac
EOF

	Házlo ejecutable:

chmod 0755 $LFS/etc/rc.d/init.d/create_ramdisk

	create_ramdisk debería ser el primer guión ejecutado por init,
	así que ajustamos este enlace:
	/etc/rc.d/rcsysinit.d/S00create_ramdisk -> ../init.d/create_ramdisk

cd $LFS/etc/rc.d/rcsysinit.d
ln -s ../init.d/create_ramdisk S00create_ramdisk


6. Instala el Cargador de Arranque isolinux
   ----------------------------------------

	También necesitamos un cargador de arranque en el CD para que arranque
	el núcleo y el disco virtual en memoria (ramdisk). lilo y grub son buenos pero perfecto para
	un CD es isolinux (viene con syslinux). Asumo que el paquete comprimido syslinux-1.67.tar.bz2
	ya está emplazado en $LFS/usr/src.

cd $LFS/usr/src
bzcat syslinux-1.72.tar.bz2 | tar x

mkdir $LFS/isolinux
cp syslinux-1.72/isolinux.bin $LFS/isolinux/

	Como todos los archivos asociados con el proceso de arranque tienen que
	estar en un mismo directorio, tenemos que mover el núcleo y el resto de 
	/boot a /isolinux.

mv $LFS/boot/* $LFS/isolinux

	Ahora creamos un enlace simbólico de boot a isolinux.

cd $LFS/
rmdir boot
ln -s isolinux boot

	El núcleo y Cía. pueden ser encontardos en /boot otra vez.
	Pero isolinux todavía necesita un fichero de configuración,
	por tanto lo crearemos ahora:

cat > $LFS/isolinux/isolinux.cfg << "EOF"
default bootcd

label bootcd
  kernel lfskernel
  append initrd=initrd.gz root=/dev/ram0 init=/linuxrc ramdisk_size=16384
EOF

	isolinux está ahora completamente instalado.


7. Crear un disco virtual en memoria (ramdisk) inicial
   ---------------------------------------------------

	¡¡¡ Pero antes debemos cambiar el /etc/fstab del LFS !!!
	Borramos todas las entradas que no necesitemos (por ejemplo
	todos los /dev/hd*). Sólo necesitamos proc (y quizás devfs, devpts)

vi $LFS/etc/fstab

	No te preocupes de montar el sistema de fichero "/".
	Será montado por linuxrc desde el initrd.

	Lo mejor es borrar también los siguientes enlaces:

rm $LFS/etc/rc.d/rc3.d/S20network
rm $LFS/etc/rc.d/rc0.d/K80network
rm $LFS/etc/rc.d/rc6.d/K80network
rm $LFS/etc/rc.d/rcsysinit.d/S40mountfs
rm $LFS/etc/rc.d/rcsysinit.d/S30checkfs

	Ahora creamos el fichero imagen initrd y el sistema
	de ficheros.

dd if=/dev/zero of=$LFS/boot/initrd bs=1024 count=6144
mke2fs -m 0 -i 1024 -F $LFS/boot/initrd

mount -o loop $LFS/boot/initrd $LFS/mnt
cd $LFS/mnt
mkdir bin lib dev proc mnt
cp $LFS/bin/{bash,mount,grep,umount,echo} bin/
cp $(find $LFS -name "test" -type f) bin/
cp $(find $LFS -name "chroot" -type f) bin/
cp $(find $LFS -name "pivot_root" -type f) bin/
cp $LFS/lib/{libncurses.so.5,libdl.so.2,libc.so.6,ld-linux.so.2} lib/
cp -dR $LFS/dev/{console,hd?,scd*,null,ram*} dev/
ln -s bash bin/sh
ln -s test bin/[

	Si prefieres usar isoinfo en vez de que mount detecte el CD con LFS,
	puedes copiar también isoinfo dentro del disco virtual en memoria inicial.

cp $(find $LFS -name "isoinfo" -type f) bin/

	El primer programa ejecutado por el núcleo es /linuxrc. Como no 
	existe lo creamos. Nuestro guión encontrará el CD en el dispositivo
	CD-ROM correcto y después lo montará como sistema de fichero / y
	ejecutará /sbin/init 3.


----------- copia y pega -------------

cat > $LFS/mnt/linuxrc << "EOF"
#!/bin/sh

#si quieres usar devfs y no tienes /dev/hd?, /dev/scd* entonces
#debes montar tu devfs aquí:


#ID es el volumen id / etiqueta del CD de Arranque del LFS
#si usas /bin/isoinfo o ID es un fichero en la raíz de tu CD
#de arranque de LFS
EOF

echo "ID=\"LFS_$(date +%Y%m%d)\"" >> $LFS/mnt/linuxrc

cat >> $LFS/mnt/linuxrc << "EOF"
TMP_MOUNT="/mnt"

PATH="/bin:/sbin:/usr/bin:/usr/sbin"

#este guión busca los dispositivos cdrom y entondces intenta
#encontrar el CD de LFS para montarlo como / (rootfs)
#Detecta: dispositivos IDE hda - hdn y  los SCSI scd0 - scd99
#o si usas devfs: dispositivos IDE/SCSI cdrom0 - cdrom99

#Necesitas los siguiente programas:
#- /bin/isoinfo (opcional)
#- /bin/sh (por ejemplo bash)
#- echo
#- [ (el cual es enlazado para probar)
#- mount
#- umount
#- grep
#- pivot_root
#- chroot

#Necesitas los siguientes dispositivos:
#- /dev/hd* o /dev/scd* o /dev/cdrom/cdrom*
#- /dev/null

#Necesitas los siguientes directorios:
#- /proc
#- $TMP_MOUNT

if [ -e "/bin/isoinfo" ]; then
  CHECK_TYPE="isoinfo"
else
  CHECK_TYPE="try_mount"
fi

if [ ! -d "/proc/" ]; then
  mkdir /proc
fi

mount -n proc /proc -t proc

#1. busca los dispositivos cdrom y los añade a CDROM_LIST

CDROM_LIST=""

#¿tenemos devfs? (entonces es muy fácil)
if [ -d "/dev/cdrom/" ]; then
  for cdrom_device in /dev/cdrom/cdrom[0-99]
  do
    if [ -e "$cdrom_device" ]; then
      CDROM_LIST="$CDROM_LIST $cdrom_device"
    fi
  done
else #buscamos en el árbol de proc a los dispositivos ide cdrom
  for ide_channel in /proc/ide/ide[0-9]
  do
    if [ ! -d "$ide_channel" ]; then
     break
    fi
    for ide_device in hda hdb hdc hdd hde hdf hdg hdh hdi hdj hdk hdl hdm hdn
    do
      device_media_file="$ide_channel/$ide_device/media"
      if [ -e "$device_media_file" ]; then
        grep -i "cdrom" $device_media_file > /dev/null 2>&1
        if [ $? -eq 0 ]; then
          if [ -e "/dev/$ide_device" ]; then
            CDROM_LIST="$CDROM_LIST /dev/$ide_device"
          fi
        fi
      fi
    done
  done
  for scsi_cdrom in /dev/scd[0-99]
  do
    if [ -e "$scsi_cdrom" ]; then
      CDROM_LIST="$CDROM_LIST $scsi_cdrom"
    fi
  done
fi

#2. ahora intentamos encontrar el CD de arranque de LFS (usamos el ID como 
#identificación)

LFS_CDROM_DEVICE=""
echo "Usando $CHECK_TYPE"
for cdrom_device in $CDROM_LIST
do
  echo -n "Probando $cdrom_device ... "

  if [ "$CHECK_TYPE" = "try_mount" ]; then
    mount -n -t iso9660 $cdrom_device $TMP_MOUNT > /dev/null 2>&1
    media_found=$?
  fi
  if [ "$CHECK_TYPE" = "isoinfo" ]; then
    isoinfo -d -i $cdrom_device > /dev/null 2>&1
    media_found=$?
    if [ $? -eq 2 ]; then
      isoinfo -V $cdrom_device > /dev/null 2>&1
      media_found=$?
    fi
  fi

  if [ $media_found -eq 0 ]; then

    echo -n "Encontado el medio"
    if [ "$CHECK_TYPE" = "try_mount" ]; then
      [ -e "$TMP_MOUNT/$ID" ]
      media_lfs=$?
    fi
    if [ "$CHECK_TYPE" = "isoinfo" ]; then
      isoinfo -d -i $cdrom_device | grep -i "Volume id:" | grep "$ID" \
      > /dev/null 2>&1
      media_lfs=$?
      if [ $? -eq 2 ]; then
        isoinfo -V $cdrom_device | grep "$ID" > /dev/null 2>&1
        media_lfs=$?
      fi
    fi

    if [ "$CHECK_TYPE" = "try_mount" ]; then
      umount -n $cdrom_device > /dev/null 2>&1
    fi

    if [ $media_lfs -eq 0 ]; then
      echo ", CD de arranque LFS encontrado. ¡Listo!"
      LFS_CDROM_DEVICE="$cdrom_device"
      break;
    else
      echo ", ningún CD de arranque LFS."
    fi

  else
    echo "ningún medio "
  fi
done


#3. Monta el CD como / (root fs)
if [ "$LFS_CDROM_DEVICE" = "" ]; then

  echo "¡¡¡Ningún CD de LFS encontrado!!!"
  exit 1

else

  echo "Arrancando desde $LFS_CDROM_DEVICE ..."

  mount -n -o ro -t iso9660 $LFS_CDROM_DEVICE $TMP_MOUNT
  cd $TMP_MOUNT
  pivot_root . mnt
  umount -n /mnt/proc >/dev/null 2>&1
  exec chroot . sh -c 'umount -n /mnt >/dev/null 2>&1;\
  exec -a init.new /sbin/init 3'\
  <dev/console >dev/console 2>&1

fi
EOF

--------------------------------------


	Para hacer que el guión se ejecute

chmod 0755 $LFS/mnt/linuxrc

	Bien, de esto se trata. Desmonta la imagen y comprímela.

cd $LFS/
umount $LFS/mnt
gzip $LFS/boot/initrd


8. Tostar el CD de Arranque
   ------------------------

	Si tienes un CD-RW tomarías este para probar. Cuando tu sistema
	arranque bastante bien desde el CD puedes tostarlo en un CR-R.
	(Te doy este aviso porque conseguí este truco después de tostar
	aproximadamente 10 CD-Rs que no funcionaron ;-)

	Antes de comenzar a tostar, comprueba el tamaño de tu árbol LFS:

du -h $LFS/

	Borra todo aquello que no necesites en un CD de Arranque. (por ejemplo /usr/src/*)

	Dado que linuxrc debe ser capaz de identificar el CD tienes que crear un
	archivo llamado "LFS_YYYYMMDD". (Pero sólo si tú no usas isoinfo)

touch $LFS/LFS_$(date +%Y%m%d)

	Ahora tuesta el sistema LFS en el CD

	¡Nota!
	dev=0,0,0 es el número del dispositivo de tu grabadora de CD
	Comprueba tus dispositivos SCSI con "cdrecord -scanbus"
	speed=4 debería cambiarse a la (max) velocidad de tu grabadora de CD.
	¡Si estás usando un CD-RW añade blank=fast al comando cdrecord!

cd $LFS/
mkisofs -R -l -L -D -b isolinux/isolinux.bin -c isolinux/boot.cat \
-no-emul-boot -boot-load-size 4 -boot-info-table -V "LFS_$(date +%Y%m%d)" \
$LFS | \
cdrecord -v -eject dev=0,0,0 speed=4 -


9. Reinicia y disfruta
   -------------------

	Reinicia y haz que tu Bios arranque desde CD.
	Disfruta de los mensajes del núcleo y el símbolo de sistema del login ;-)

------------------------------------------------------------------
 Si tienes algunas ideas, sugerencias o encotraste una errata, 
 envíame un correo a:
 Thomas Foecking <thomas@foecking.de>
 Christian Hesse <mail@earthworm.de>
------------------------------------------------------------------