En el artículo
anterior, hemos compilado un kernel y llegado a arrancar desde disco duro. En este vamos a arrancar desde
USB,
aunque todavía no vamos a hacerlo de forma definitiva, pero nos servirá
para probar cosas y hacer unos últimos ajustes en la configuración.
Hay dos razones por las que lo que hemos hecho anteriormente no nos ha servido para arrancar desde
USB. La primera es que el kernel necesita colaboración por parte de algún proceso para poder reconocer los
USB, lo que significa que hay que crear un
initrd para ello. La segunda es que los nombres de los dispositivos pueden cambiar, así que hay que localizar la partición
root usando su
UUID. El problema es que el kernel tampoco puede leer los
UUID de las particiones sin ayuda por parte de algún proceso externo, o sea que tenemos una doble razón por la cual necesitamos un
initrd.
Copiando el kernel de otra distro
Para comprobar que el problema es del kernel y/o del
initrd y que el resto de nuestro sistema
LFS funciona correctamente, una cosa que podemos hacer es usar un kernel de otra distro, con su correspondiente
initrd, para arrancar nuestro
LFS. Así de paso nos sirve como kernel alternativo en caso de que el nuestro nos dé algún problema. No está de más tener algo así.
Para esto voy a recurrir a un
LiveUSB de
Debian que tengo por ahí. Lo que voy a hacer es extraerle el kernel con su
initrd, módulos y todo lo que dependa de él y meterlo en el
LFS que estamos creando. En realidad no es un
LiveUSB, es un
Debian testing completo instalado en un
USB. Es lo que uso como disco de rescate.
En vuestro caso, no necesitáis una
Debian para hacer esto.
Debería serviros cualquier distro. Eso sí: la forma de hacerlo es
ligeramente distinta en cada distro, así que deberíais fijaros bien en
cómo son los ficheros que necesitáis y extraer esos. La principal
diferencia será el número de versión del kernel.
Tampoco hace falta que esté instalada en un
USB. Yo he usado esta para estar completamente seguro de que funciona en un
USB, pero otras también deberían arrancar desde
USB aunque estén instaladas en el disco duro. Más abajo hago lo mismo con el kernel de mi
ArchLinux que está instalada en un
SSD.
Hay dos formas de hacer esto. Una es arrancar con el
USB,
disco duro o dispositivo en el que está el kernel que queréis extraer.
La otra es montar la partición correspondiente en algún punto de sistema
de ficheros de la distro que estáis usando para crear
LFS. En el primer caso necesitáis algún otro
USB,
carpeta de red, o cualquier otro medio que os permita pasar el kernel
extraído a vuestra máquina. En el segundo caso es necesario tener acceso
a
boot y a
root, así que si usáis una partición
boot aparte, tenéis que montarla también.
En mi caso he optado por la primera forma. Más que nada porque he
usado otra máquina, así que la segunda no era factible. Lo primero que
he hecho ha sido arrancar con el
USB de
Debian y enchufar el que estoy usando para instalar
LFS. Habréis notado que la
swap está en
sdc2 y la partición raíz en
sdc3. Eso es porque en
sdc1 tengo una partición
vfat que uso para intercambiar ficheros incluso con equipos
Windows, así que me sirve para pasar el kernel a la otra máquina. Curiosamente, al enchufar el
USB le ha asignado el nombre de dispositivo
sdc. No tendría por qué ser así. Es casualidad.
Lo que he hecho a continuación es montar la partición
vfat de mi
USB y crear en ella un archivo comprimido con el kernel de
Debian
y todos los ficheros que necesita para arrancar. Estos ficheros son los
que cambian de una distro a otra. En primer lugar, para saber con qué
kernel estáis arrancando, en caso de que haya más de uno, podéis mirar
los ficheros de configuración del gestor de arranque que uséis. Estarán
en un directorio dentro de
/boot. En ese mismo fichero de configuración aparece también el
initrd que usa. Tenéis que añadir los ficheros de esa misma versión del kernel que estén en
/boot, además de los módulos, que estarán en
/lib/modules.
Todo esto hay que hacerlo desde el directorio raíz para que el fichero
que estamos generando se descomprima después correctamente.
Otro directorio que hay que tener en cuenta es el del
firmware. Normalmente es
/lib/firmware
y no lleva número de versión porque suele ser siempre igual. Se trata
de drivers privativos que se distribuyen en binario porque el fabricante
no proporciona el código fuente. Si nuestro equipo funciona bien sin
software privativo podríamos omitirlo.
linux@debian:~$ sudo mkdir /mnt/sdc1
linux@debian:~$ sudo mount /dev/sdc1 /mnt/sdc1
linux@debian:~$ cd /
linux@debian:/$ tar cvJf /mnt/sdc1/linux-3.2.0-2-debian.txz \
> boot/vmlinuz-3.2.0-2-amd64 \
> boot/initrd.img-3.2.0-2-amd64 \
> boot/System.map-3.2.0-2-amd64 \
> lib/firmware/ \
> lib/modules/3.2.0-2-amd64/
linux@debian:/$ sudo umount /dev/sdc1
linux@debian:/$ exit
Ahora ya puedo apagar el equipo
Debian (siempre de forma controlada, por supuesto) y enchufar el
USB con el kernel extraído en mi máquina. En esta máquina, la partición
vfat del
USB se monta en
/media/USBDATA. El siguiente paso es instalarlo en
LFS usando el script que tenemos para ello. El fichero
txz que hemos generado es compatible con él, si hemos puesto las opciones de tar correctas y hemos comprimido desde el raíz.
[~]$ sudo lfsinst /media/USBDATA/linux-3.2.0-2-debian.txz
Voy a hacer lo mismo con el kernel de
Arch. No tengo la misma garantía que con el de
Debian,
pero intuyo que va a funcionar y además sirve como ejemplo de cómo
hacer lo mismo con otra distro, ya que es parecido pero diferente. En
este caso estoy lanzando los comandos en mi máquina principal, así que
no tengo que montar nada. Es la misma máquina en la que estoy instalando
LFS.
[~]$ cd /
[/]$ tar cvJf ~/lfs/linux-3.8.4-1-ARCH.txz \
> boot/vmlinuz-linux \
> boot/initramfs-linux.img \
> lib/firmware \
> lib/modules/3.8.4-1-ARCH \
> lib/modules/extramodules-3.8-ARCH/ \
> lib/modprobe.d/
[/]$ cd ~/lfs
[~/lfs]$ sudo lfsinst ~/lfs/linux-3.8.4-1-ARCH.txz
Ya tengo nada menos que dos kernels alternativos en mi
LFS. Con uno sería suficiente, pero así confirmo que es factible arrancar desde nuestro sistema. Esos kernels tienen sus propios
initrd en los que estarán las herramientas que el kernel necesita para detectar el
USB y luego localizar y montar la partición raíz.
Con esto podemos solucionar el primer problema que teníamos: usar un
initrd que soporte
USB. Falta el segundo: localizar la partición por
UUID. Para ello, en primer lugar, hay que averiguar el
UUID de la partición raíz de nuestro
LFS. Esto se puede hacer examinando el directorio
/dev/disk/bu-uuid, donde el kernel deja todos los dispositivos que detecta organizados por
UUID.
[~/lfs]$ ls -l /dev/disk/by-uuid/ | grep sdc3
lrwxrwxrwx 1 root root 10 Apr 2 18:55 dd02b529-840e-4ffa-9433-e2709dffd81c -> ../../sdc3
O sea que el
UUID de mi partición raíz de
LFS es
dd02b529-840e-4ffa-9433-e2709dffd81c. Este
UUID no cambia nunca lo enchufemos donde lo enchufemos mientras no formateemos la partición, así que es seguro localizarla por este
UUID.
Ya tenemos todo lo que necesitamos para arrancar desde
USB. Ahora sólo falta actualizar los ficheros de configuración de los gestores de arranque. Sigo teniendo instalados tanto
grub como
Syslinux,
así que voy a probar con los dos. Hay que añadir los dos nuevos kernels
(o los que hayáis extraido vosotros) teniendo cuidado de especificar el
initrd. Además hay que cambiar el nombre de la partición raíz por el
UUID. Esto lo voy a hacer también con el kernel de
LFS, aunque de momento no va a funcionar desde
USB.
Primero mi gestor de arranque favorito:
Syslinux.
[~/lfs]$ sudo lfs
root:/# cat > /boot/extlinux/extlinux.conf << "EOF"
> PROMPT 1
> TIMEOUT 50
> DEFAULT lfs
>
> LABEL lfs
> LINUX ../vmlinuz-3.5.2-lfs-7.2
> APPEND root=UUID=dd02b529-840e-4ffa-9433-e2709dffd81c ro
>
> LABEL lfsdebian
> LINUX ../vmlinuz-3.2.0-2-amd64
> APPEND root=UUID=dd02b529-840e-4ffa-9433-e2709dffd81c ro
> INITRD ../initrd.img-3.2.0-2-amd64
>
> LABEL lfsarch
> LINUX ../vmlinuz-linux
> APPEND root=UUID=dd02b529-840e-4ffa-9433-e2709dffd81c ro
> INITRD ../initramfs-linux.img
> EOF
Ahora hacemos lo mismo con el
grub.
root:/# cat > /boot/grub/grub.cfg << "EOF"
> # Begin /boot/grub/grub.cfg
> set default=0
> set timeout=5
>
> insmod ext2
> set root=(hd0,3)
>
> menuentry "GNU/Linux, Linux 3.5.2-lfs-7.2" {
> linux /boot/vmlinuz-3.5.2-lfs-7.2 root=UUID=dd02b529-840e-4ffa-9433-e2709dffd81c ro
> }
>
> menuentry "GNU/Linux, Linux 3.2.0-2-amd64 debian" {
> linux /boot/vmlinuz-3.2.0-2-amd64 root=UUID=dd02b529-840e-4ffa-9433-e2709dffd81c ro
> initrd /boot/initrd.img-3.2.0-2-amd64
> }
>
> menuentry "GNU/Linux, Linux 3.8.4-1 arch" {
> linux /boot/vmlinuz-linux root=UUID=dd02b529-840e-4ffa-9433-e2709dffd81c ro
> initrd /boot/initramfs-linux.img
> }
> EOF
Ahora podemos probar a arrancar con los dos gestores de arranque para
ver si funciona. Claro, el detalle que nos falta es que no se puede
arrancar con dos gestores de arranque a la vez, así que sólo puede haber
uno configurado para arrancar el
USB. Cuando instalemos uno en el
MBR quitará al otro y viceversa, así que para cambiar de uno a otro hay que usar el comando que instala en el
MBR el gestor de arranque que queremos probar.
Para arrancar con
Syslinux:
root:/# cat /usr/share/syslinux/mbr.bin > /dev/sdc
Ojo:
Syslinux necesita que la partición esté marcada como
arrancable en la tabla de particiones. Esto ya lo hemos hecho en el post
anterior, así que no debería haber problema, pero no está de más
verificarlo con
fdisk.
Para arrancar con
grub:
root:/# grub-install /dev/sdc
Así que lanzamos uno de los dos comandos anteriores, probamos los dos
kernels, lanzamos el otro y volvemos a probar. Y el resultado es…
…¡Que ha funcionado tanto con
grub como con
Syslinux y con los dos kernels!!
Por ahora eso es todo. Por supuesto, tenemos que crear nuestro propio
initrd. No vamos a ser menos.
Pero eso para más adelante. En el siguiente post lo que vamos a crear
es un usuario para no tener que trabajar con la cuenta de
root.
EOF
Tomado de:
http://wrongshell.wordpress.com/2013/04/07/linux-from-scratch-xxxii-arrancando-desde-usb-con-un-kernel-alternativo/