Tres formas de instalar GRUB
En la mayoría de los casos, un usuario de Linux rara vez necesitará enfrentarse a la instalación manual de GRUB, el gestor de arranque más común para Linux, ya que en el momento de la instalación de su distribución favorita, ésta lo hará por él. En muchos casos, puede ser suficiente para el usuario medio saber cómo editar el fichero /boot/grub/menu.lst
para modificar las entradas del menú de arranque de acuerdo a sus necesidades. Sin embargo, sigue habiendo casos en los que necesitaremos hacer esta instalación manualmente.
Por ejemplo, en entradas anteriores vimos cómo instalar manualmente GRUB en una memoria USB para poder arrancar múltiples sistemas operativos desde ella:
También vimos cómo, en caso de estar trabajando sobre un fakeRAID, el instalador de la distribución no es capaz de instalar GRUB con éxito, teniendo que hacerlo nosotros mismos manualmente:
Esta entrada pretende resumir las diferentes técnicas que ya habíamos visto previamente en un único documento que sirva de referencia, así como dar algunos detalles adicionales sobre el funcionamiento interno de GRUB. Por supuesto, toda esta información ya existe, como no podía ser de otra forma, en el manual de GRUB.
Para empezar, convendría recordar los componentes que conforman GRUB. Los ficheros implicados en la instalación de GRUB en el sector de arranque los encontraremos en /boot/grub/
, pero éstos realmente provienen de /usr/lib/grub/i386-pc/
o /usr/lib/grub/x86_64-pc/
, según la arquitectura:
-rw-r--r-- 1 root root 7552 2008-04-12 00:44 e2fs_stage1_5 -rw-r--r-- 1 root root 7424 2008-04-12 00:44 fat_stage1_5 -rw-r--r-- 1 root root 8192 2008-04-12 00:44 jfs_stage1_5 -rw-r--r-- 1 root root 6848 2008-04-12 00:44 minix_stage1_5 -rw-r--r-- 1 root root 9248 2008-04-12 00:44 reiserfs_stage1_5 -rw-r--r-- 1 root root 512 2008-04-12 00:44 stage1 -rw-r--r-- 1 root root 108328 2008-04-12 00:44 stage2 -rw-r--r-- 1 root root 8872 2008-04-12 00:44 xfs_stage1_5
En primer lugar, tenemos el stage1
, un fichero de apenas 512 bytes, lo justo para que quepa en el Master Boot Record (MBR) o en el sector de arranque de alguna de las particiones primarias. En éstos 512 bytes apenas hay espacio para un poco de código de inicialización del sistema y para cargar el stage2
, que es donde está todo el código de GRUB. Como el stage1
no tiene capacidad, en tan poco código, para buscar en un sistema de ficheros dónde está el stage2
, hay que escribir un stage1
modificado que lleve la posición exacta del fichero stage2
en disco para que pueda leerlo directamente. El problema de ese procedimiento es que si movemos el stage2
de sitio (un movimiento físico dentro del disco, aunque realmente no cambie de sitio en la jerarquía de directorios), el stage1
no sabrá encontrar al stage2
.
Por eso GRUB también lleva varios ficheros sistemadeficheros_stage1_5
. Cuando instalamos GRUB en el MBR, el stage1_5
se escribe en el hueco que hay entre el sector de arranque, de 512 bytes, y la primera partición, que empieza tras los primeros 32 KiB del disco (ver Montar una imagen raw de Qemu. Los primeros 32 Kbytes de un disco.). El stage1_5
, que ya puede contener algo más de código, sí que es capaz de entender un tipo de sistema de ficheros (ext2/3, JFS, ReiserFS, XFS, FAT) lo suficiente para poder localizar en él el stage2
sin problemas, aunque éste haya cambiado de sitio físicamente en el disco.
Por tanto, al arrancar un sistema con GRUB instalado en el MBR, donde los ficheros de /boot/grub/
están en un sistema de ficheros ext2/3, lo que ocurrirá es que el procesador cargará el código de stage1
del primer sector. Este código a su vez arrancará el e2fs_stage1_5
, que estará en el segundo sector del disco. Y éste, a su vez, con capacidad de moverse por el sistema de ficheros, localizará el stage2
y lo cargará. Ahora ya tendremos el GRUB completamente cargado y listo para gestionar todos los sistemas de ficheros soportados. En este punto ya podremos usar comandos de la shell de GRUB de manejo de ficheros como find
, cat
, cmp
o el autocompletado de los nombres de ficheros/directorios con la tecla TAB
.
GRUB usa una nomenclatura propia para discos duros y particiones. Los discos duros son (hd0)
, (hd1)
, (hd2)
, (hd3)
, etc. Las particiones del disco (hdX)
son (hdX,0)
, (hdX,1)
, (hdX,2)
, etc. La cuenta siempre empieza por cero (0), y es importante tenerlo siempre presente porque en los ficheros de dispositivo de partición (p.e. /dev/sda1
) la cuenta empieza por uno (1).
Y es precisamente ese el meollo de GRUB y la fuente más importante de problemas, que qué disco es (hd0)
y qué disco es (hd3)
según la BIOS. Hace unos años, cuando los PCs sólo sabían arrancar de CD/DVD, de disquete, y los discos siempre eran IDE, saber esto era extremadamente fácil. El disco maestro del canal IDE primario siempre iba a ser (hd0)
, y por detrás se ordenarían el disco esclavo del canal IDE primario y los discos del canal IDE secundario. Hoy en día, esto se ha complicado muchísimo: En nuestro PC conviven discos IDE, discos SATA (en ocasiones incluso tenemos varias controladoras), discos externos USB y otras extravagancias como discos en fakeRAID. ¿Cuál de ellos es el primero y cuál el segundo? El orden de arranque que establecemos en la BIOS es el factor que lo determina, pero ese orden lo alteraremos si durante el arranque pulsamos la tecla que, en nuestra placa base, saque el menú de selección del dispositivo de arranque (típicamente el Boot menu).
El asunto se complica porque dentro de Linux, los dispositivos que se asignen al disco, no tendrán, en la mayoría de los casos, nada que ver con ese orden. Ya dentro del sistema operativo, tendremos cosas como /dev/hda
, /dev/hdb
, /dev/sda
, /dev/sdi
y /dev/mapper/dispositivo_fakeraid
, nada que nos dé una pista sobre quién es (hd0)
y quién es (hd3)
. Al menos, algo sabemos seguro, y es que (hd0)
es el disco del que la BIOS va a arrancar.
Así, para instalar GRUB en un disco (por ejemplo, en uno USB externo) desde nuestra distribución actual de Linux, podríamos, simplemente, usar el grub-install
, al que le tenemos que indicar dónde está montada la partición donde tiene copiar los ficheros *stage*
dentro de /boot/grub/
, y el dispositivo donde escribir el GRUB. Puede ser un dispositivo de disco (p.e. /dev/sdi
) y el GRUB se escribirá en el MBR; o puede ser un dispositivo de partición (p.e. /dev/sdi1
) y el GRUB se escribirá en el sector de arranque de la partición:
$ sudo grub-install --no-floppy --root-directory=/media/disk /dev/sdi Probing devices to guess BIOS drives. This may take a long time. Installing GRUB to /dev/sdi as (hd4)... Unknown partition table signature Installation finished. No error reported. This is the contents of the device map /media/disk/boot/grub/device.map. Check if this is correct or not. If any of the lines is incorrect, fix it and re-run the script `grub-install'. (hd0) /dev/sda (hd1) /dev/sdb (hd2) /dev/sdc (hd3) /dev/sdh (hd4) /dev/sdi
Vemos que grub-install
intenta emparejar los ficheros de dispositivo de los discos con los números de disco que la BIOS le ha asignado al disco. Esto es una potencial fuente de problemas, porque hemos instalado GRUB en sdi
especificando que es el cuarto disco (hd4)
, pero cuando vayamos a arrancar de este disco, para la BIOS será el primer disco (hd0)
.
Por eso, es mucho mejor, antes de ejecutar grub-install
, especificar claramente en el fichero device.map
del directorio /boot/grub/
del disco en el que queremos instalar GRUB, que el dispositivo en el que estamos instalando GRUB será (hd0)
cuando vayamos a arrancar de él:
$ cd /media/disk $ sudo mkdir -p boot/grub $ sudo vi boot/grub/device.map $ cat boot/grub/device.map (hd0) /dev/sdi $ sudo grub-install --no-floppy --root-directory=/media/disk/ /dev/sdi Installing GRUB to /dev/sdi as (hd0)... Installation finished. No error reported. This is the contents of the device map /media/disk//boot/grub/device.map. Check if this is correct or not. If any of the lines is incorrect, fix it and re-run the script `grub-install'. (hd0) /dev/sdi
Fijémonos en que el propio fichero de dispositivo también es muy variable. En el caso de memorias USB, sólo depende del orden en el que las conectemos al ordenador. Por eso, es importante revisar el fichero device.map
cada vez que necesitemos reinstalar GRUB.
Desafortunadamente, con según que tipos de ficheros de dispositivo, el comando grub-install
se lía, porque no puede obtener el número de disco de la BIOS, incluso aunque se lo especifiquemos en el device.map
. Es el caso, por ejemplo, de los fakeRAID:
$ cat /boot/grub/device.map /dev/mapper/nvidia_bdehcbaa (hd0) $ sudo grub-install --no-floppy '(hd0)' /dev/mapper/nvidia_bdehcbaa3 does not have any corresponding BIOS drive.
En estos casos, podemos usar la shell de GRUB que tenemos a nuestra disposición, que supone nuestro segundo método de instalación de GRUB. Esta shell es similar a la línea de comandos a la que podemos acceder desde el GRUB real que tenemos al arrancar, pero con sus peculiaridades, dado que se ejecuta dentro de un sistema operativo y no bajo la BIOS. La shell de GRUB dispone del comando device
, que nos permite asociar a mano ficheros de dispositivo con discos y particiones de la BIOS:
$ sudo grub --device-map=/dev/null [ Minimal BASH-like line editing is supported. For the first word, TAB lists possible command completions. Anywhere else TAB lists the possible completions of a device/filename. ] grub> device (hd0,2) /dev/mapper/nvidia_bdehcbaa3 device (hd0,2) /dev/mapper/nvidia_bdehcbaa3 grub> device (hd0) /dev/mapper/nvidia_bdehcbaa device (hd0) /dev/mapper/nvidia_bdehcbaa grub> root (hd0,2) root (hd0,2) grub> setup (hd0) setup (hd0) Checking if "/boot/grub/stage1" exists... yes Checking if "/boot/grub/stage2" exists... yes Checking if "/boot/grub/e2fs_stage1_5" exists... yes Running "embed /boot/grub/e2fs_stage1_5 (hd0)"... 16 sectors are embedded. succeeded Running "install /boot/grub/stage1 (hd0) (hd0)1+16 p (hd0,2)/boot/grub/stage2 /boot/grub/menu.lst"... succeeded Done.
La tercera forma de instalar GRUB es por medio de la línea de comandos del GRUB real, el que tenemos en el momento del arranque. Desde un GRUB instalado en un disco/partición, instalamos otro GRUB en otro disco/partición. Este procedimiento escribirá el stage1
en el sector de arranque, y el stage1_5
en el hueco disponible si procede, pero no copiará los ficheros *stage*
al directorio /boot/grub/
de la partición destino. Eso lo tenemos que hacer de forma manual previamente:
$ mkdir -p /media/disk/boot/grub $ cp -p /usr/lib/grub/i386-pc/* /media/disk/boot/grub/
Una vez que el disco/partición destino ya tiene los ficheros *stage*
, rearrancaremos el sistema y en el propio menú de GRUB:
pulsaremos la tecla “C
” para entrar en su línea de comandos. En ella, buscamos en qué discos tenemos los ficheros *stage*
con el comando find
. Tenemos que encontrarlos en al menos dos sitios, en el disco/partición desde el que hemos arrancado GRUB, y en el disco/partición en el que vamos a instalar GRUB:
grub> find /boot/grub/stage2 (hd0,0) (hd1,0)
Y finalmente, usamos el comando setup
indicando el dispositivo donde escribiremos el stage1
(puede ser un disco o una partición) y la partición donde ha de buscar los ficheros *stage*
:
grub> setup (hd1) (hd1,0)
La gran ventaja de este sistema es que ahora GRUB no se fía en ningún momento de lo que le diga el sistema operativo, y usará los números de unidades que le pase directamente la BIOS, una garantía para no equivocarnos.
Por cierto, si en algún caso necesitamos deshacernos del GRUB que tenemos instalado en el MBR, podemos usar el ms-sys
(Ubuntu y Debian eliminan ms-sys de sus repositorios) en Linux y el MBRFix
en Windows (Instalar Windows XP desde una memoria USB que arranque BartPE) para instalar el MBR típico de los sistemas operativos de Microsoft, que lo único que hace es cargar el sector de arranque de la partición que esté activa (que, por supuesto, podría dar la casualidad de que contuviera un stage1
de GRUB, claro).
:wq
Relacionada: Como recuperar un grub http://vierito.es/wordpress/2008/09/28/how-to-como-recuperar-grub/
Excelente, como siempre.
Saludos.
La verdad es que da gusto leer artículos como este; gracias a ti se aprenden muchas cosas nuevas
@wacka, @Tito, @Jan ¡Gracias a vosotros por pasaros por aquí y dejar vuestros comentarios!