Desde o lançamento do Slackware64 que venho lutando com o meu gerenciador de boot, sem muita satisfação com as soluções empregadas. Usei o lilo por muito tempo, mas o simples fato de não ter que reescrever a MBR a cada novo kernel que instalo, me fez abandonar a simplicidade do lilo, pelo trabalho mais adequado às minhas necessidades, feito pelo grub.

Por algum motivo, até imaginável, o Slackware64 não está vindo com o pacote do grub, o que deixava com algumas poucas opções:

  • usar o lilo e reescrever a MBR a cada kernel que teste;
  • instalar outras distribuição em um as minhas partições de teste para usar o grub dela;
  • compilar o grub;

Para mim a escolha mais natural seria a opção 3. No entanto haviam apenas um pequeno problema nesta escolha: o grub não compila em sistemas 64bits, sem algum sofrimento e bibliotecas 32bits adicionais, o que o Slackware64 ainda não estava adequadamente preparado. Dado ao pouco tempo disponível no final do semestre, por algum tempo utilizei as duas primeiras opções.

Após a instalação da nova versão do Kubuntu, um colega reclamou que o novo grub estava totalmente estranho e que não o queria mais em sua máquina. “Estranho”+”grub” = “grub2”

Isto mesmo, finalmente deram um gás ao grub e a versão 2 deu passos de gente grande. Madura, estável, modular, um pouco diferente e, acima de tudo, compila em 64bits sem traumas.

Compilando o grub2

Criar pacotes para o Linux tem se tornado uma tarefa muito fácil, seja pela maturidade dos códigos ou pela quantidade de informação e ferramentas como scripts disponíveis na rede. Com o grub2 não foi diferente. Essencialmente tive que fazer apenas algumas pequenas mudanças ao Slackbuild do grub, disponível com o Slackware 32bits.

As alterações não passaram de remover os diversos patchs aplicados ao grub 1 e alterar a versão padrão para 1.98, que é uma versão alpha do grub2. A listagem a seguir, apresenta o SlackBuild alterado para o grub2:

#!/bin/sh
CWD=`pwd`
TMP=${TMP:-/tmp}
PKG=$TMP/package-grub

VERSION=1.98
ARCH=${ARCH:-i486}
BUILD=1

if [ "$ARCH" = "i386" ]; then
  SLKCFLAGS="-O2 -march=i386 -mcpu=i686"
elif [ "$ARCH" = "i486" ]; then
  SLKCFLAGS="-O2 -march=i486 -mtune=i686"
elif [ "$ARCH" = "s390" ]; then
  SLKCFLAGS="-O2"
elif [ "$ARCH" = "x86_64" ]; then
  SLKCFLAGS="-O2"
fi

if [ ! -d $TMP ]; then
  mkdir -p $TMP
fi
rm -rf $PKG
mkdir -p $PKG
cd $TMP
rm -rf grub-$VERSION
tar xzvf $CWD/grub-$VERSION.tar.gz || exit 1
cd grub-$VERSION

chown -R root:root .
find . -perm 777 -exec chmod 755 {} \;
find . -perm 664 -exec chmod 644 {} \;
CFLAGS="$SLKCFLAGS" \
./configure \
  --prefix=/usr \
  --sysconfdir=/etc \
  --infodir=/usr/info \
  --mandir=/usr/man

make -j3 || exit 1
make install DESTDIR=$PKG || exit 1

( cd $PKG
  find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
  find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null
)

# Compress and if needed symlink the man pages:
if [ -d $PKG/usr/man ]; then
  ( cd $PKG/usr/man
    for manpagedir in $(find . -type d -name "man*") ; do
      ( cd $manpagedir
        for eachpage in $( find . -type l -maxdepth 1) ; do
          ln -s $( readlink $eachpage ).gz $eachpage.gz
          rm $eachpage
        done
        gzip -9 *.?
      )
    done
  )
fi

# Compress info pages and purge "dir" file from the package:
if [ -d $PKG/usr/info ]; then
  ( cd $PKG/usr/info
    rm -f dir
    gzip -9 *
  )
fi

mkdir -p $PKG/usr/doc/grub-$VERSION
cp -a \
  AUTHORS BUGS COPYING INSTALL MAINTENANCE NEWS README THANKS TODO \
  $PKG/usr/doc/grub-$VERSION

mkdir -p $PKG/install
cat $CWD/slack-desc > $PKG/install/slack-desc

cd $PKG
makepkg -l y -c n $TMP/grub-$VERSION-$ARCH-$BUILD.txz

O script pode ser baixado do link grub.SlackBuild

Removi também o grubconfig de Kent, pois acredito, embora não o tenha testado, que ele não deva funcionar com o 2. Antes de compilar baixe, para o mesmo diretório onde está o SlackBuild, a fonte da última versão do grub2. O wget abaixo cuida deste detalhe:

wget ftp://alpha.gnu.org/gnu/grub/grub-1.98.tar.gz

Para compilar é necessário passar a arquitetura ‘x86_64’ através da variável ARCH, para o SlackBuild e aguardar a compilação do pacote:

ARCH=x86_64 . ./grub.SlackBuild

Caso tenha algum problema pode tentar com a copia da compilação deste pacote que postei no link grub-1.98-x86_64-8.txz. Em seguida instale o pacote da forma usual:

installpkg /tmp/grub-1.98-x86_64-8.txz

Para terminar a instalação, instale o grub2 na MBR com o comando abaixo:

grub-install /dev/sda

Onde /dev/sda é o seu disco principal, onde está instalado o boot do sistema. Em meu caso é o primeiro disco SATA. Se o seu boot estiver no primeiro disco IDE, o dispositivo correto será /dev/hda.
O próximo passo é configurar as opções de boot do seu sistema.

Configurando o grub

O arquivo de configuração menu.lst não existe mais no grub2. Suas configurações agora ficam no arquivo grub.cfg, que na configuração padrão é colocado em /boot/grub. Este arquivo deve conter todas as configurações necessárias para iniciar os diferentes sistemas instalados em sua máquina, bem como a carga dos módulos necessários para adicionar outros recursos como boot gráfico, animações, … além das costumeiras linhas de comando do kernel.

O grub2, além de suportar a carga de diversos módulos, ele também suporta loops, condicionais e variáveis, algo parecido a um bash shell, mas isto deve ficar para um outro texto.

O aplicativo grub-mkconfig cria um arquivo de configuração grub.cfg básico. Os bash scripts localizados em /etc/grub.d/ são utilizados pelo comando grub-mkconfig para criar o novo grub.cfg. O arquivo /etc/grub.d/README explica como utilizar e adicionar outros construtores à criação do grub.cfg.

O comando grub-mkconfig cria automaticamente um grub.cfg, com os vmlinuz em /boot. O próximo passo é criar um grub.cfg básico com este script:

grub-mkconfig -o /boot/grub/grub.cfg

As partições NTFS ou FAT32 do Windows, não serão adicionadas neste arquivo de configuração, pois os aplicativos os-prober e linux-boot-prober não existem no Slackware. O os-prober/linux-boot-prober são aplicativos do Debian e com mais algumas dependências específicas desta distribuição, as quais não tive interesse em conhecer. Não tive muito sucesso em emulá-los por isto tive que resolver estes problemas manualmente.

A listagem a seguir mostra um grub.cfg típico, gerado pelo comando grub-mkconfig:

Generating grub.cfg ...
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by /usr/sbin/grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#

### BEGIN /etc/grub.d/00_header ###
set default=0
insmod xfs
set root=(hd0,6)
search --no-floppy --fs-uuid --set ca1e5ac8-744c-4b19-a99f-ee76576bad06
if loadfont /boot/grub/unifont.pf2 ; then
  set gfxmode=640x480
  insmod gfxterm
  insmod vbe
  if terminal_output gfxterm ; then true ; else
    # For backward compatibility with versions of terminal.mod that don't
    # understand terminal_output
    terminal gfxterm
  fi
fi
set timeout=5
### END /etc/grub.d/00_header ###

### BEGIN /etc/grub.d/10_linux ###
Found linux image: /boot/vmlinuz-2.6.32-rd03
menuentry "GNU/Linux, with Linux 2.6.32-rd03" {
        insmod xfs
        set root=(hd0,6)
        search --no-floppy --fs-uuid --set ca1e5ac8-744c-4b19-a99f-ee76576bad06
        linux   /boot/vmlinuz-2.6.32-rd03 root=/dev/sda6 ro
}
menuentry "GNU/Linux, with Linux 2.6.32-rd03 (recovery mode)" {
        insmod xfs
        set root=(hd0,6)
        search --no-floppy --fs-uuid --set ca1e5ac8-744c-4b19-a99f-ee76576bad06
        linux   /boot/vmlinuz-2.6.32-rd03 root=/dev/sda6 ro single
}
Found linux image: /boot/vmlinuz-huge-2.6.29.6
menuentry "GNU/Linux, with Linux 2.6.29.6" {
        insmod xfs
        set root=(hd0,6)
        search --no-floppy --fs-uuid --set ca1e5ac8-744c-4b19-a99f-ee76576bad06
        linux   /boot/vmlinuz-huge-2.6.29.6 root=/dev/sda6 ro
}
menuentry "GNU/Linux, with Linux 2.6.29.6 (recovery mode)" {
        insmod xfs
        set root=(hd0,6)
        search --no-floppy --fs-uuid --set ca1e5ac8-744c-4b19-a99f-ee76576bad06
        linux   /boot/vmlinuz-huge-2.6.29.6 root=/dev/sda6 ro single
}
### END /etc/grub.d/10_linux ###

### BEGIN /etc/grub.d/30_os-prober ###
### END /etc/grub.d/30_os-prober ###

### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
### END /etc/grub.d/40_custom ###
done

Se observar o arquivo criado, verá que ele é separado por seções iniciadas por:

”### BEGIN /etc/grub.d/nome_do_script ###’

e terminadas por

“### END /etc/grub.d/nome_do_script ###”

Onde “nome_do_script” são os nomes dos scripts contidos no diretório /etc/grub.d/. A idéia original do grub2 é que as alterações necessárias sejam feitas nestes scripts e não no arquivo de configuração grub.cfg, como salientado no início do grub.cfg gerado “# DO NOT EDIT THIS FILE“.

Embora no grub.cfg aconselha a não editar este arquivo, uma vez que ele é gerado pelos scripts em /etc/grub.d/, obviamente vou editá-los.

Para criar uma entrada para o Windows, na partição /dev/sda1, adicione as linhas abaixo, sobre os comentários internos à seção /etc/grub.d/40_custom:

### BEGIN /etc/grub.d/40_custom ###
# Windows Vista
menuentry "Windows Vista" {
  set root=(hd0,1)
  chainloader +1
}
### END /etc/grub.d/40_custom ###

Isto é suficiente para iniciar uma instalação do Windows na partição /dev/sda1.

Firulas Gráficas

Para colocar uma imagem no boot é necessário configurar o grub2 para entrar no modo gráfico. Esta configuração deve ser feita em diversas etapas, como:

  • carregar os módulos gráficos: video e vbe
  • setar o modo gráfico: set gfxmode
  • carregar o módulo de suporte a fontes pf2: font

Vamos em frente, adicione as linhas abaixo ao seu grub.cfg:

# seta os modos vesa
set gfxmode="1024x768x24;800x600x24"
insmod video
insmod vbe

# instalar a fonte
insmod font
loadfont /boot/grub/unifont.pf2

# seleciona o modo
insmod gfxterm
set gfxmode=1024x768x24
terminal_output gfxterm

# carrega a imagem de boot
insmod png
background_image /boot/grub/imagem.png

# Seleciona as cores do menu
set menu_color_normal=light-blue/black
set menu_color_highlight=light-cyan/blue

# fixa o modo para após o boot
set gfxpayload=keep

O grub2 trabalha com fontes no formato pf2, as quais desconheço. O aplicativo grub-mkfont, presente no pacote do grub2, permite converter fontes Adobe BDF para pf2. Uma busca um pouco trabalhosa na internet permite encontrar algumas fontes BDF. Este link aponta para um arquivo com algumas destas fontes BDF.

Escolha uma fonte de seu agrado e use o grub-mkfont para convertê-los, como na linha de comando abaixo:

grub-mkfont --output=/boot/grub/unifont.pf2 font_adobe.bdf

Substitua o font_adobe.bdf pela fonte de seu interesse.

Em seguida escolha uma imagem para o background de seu boot. A imagem deve ser convertida às dimensões usadas pelo grub e para o formado png. O converte é ideal para este processo:

convert -resize 1024x768 imagem.jpg /boot/grub/imagem.png

Se por algum motivo a resolução gráfica der algum problema após o boot, remova a linha “set gfxpayload=keep”, que após iniciar uma seção do boot a resolução retorna ao normal, mas mantem o boot gráfico.

Mais Firulas

Se quiser que a imagem de boot altere a cada reinicialização do sistema, crie um script com o nome /etc/rc.d/rc.grub_image, com o conteúdo:

#!/bin/bash
#
WALL_DIR='/etc/wallpapers'
WALLPAPER=`/bin/ls -1 $WALL_DIR/ | sort --random-sort | head -1`

echo "Convert image $WALL_DIR/$WALLPAPER to grub..."
convert -resize 1024x768 $WALL_DIR/$WALLPAPER /boot/grub/image.png

Para não sobrecarregar ainda mais o boot do Slackware, sugiro adicionar sua chamada em /etc/rc.d/rc.local_shutdown. Este script é chamado, se existir, sempre que o sistema vai a modo 0 ou 6.

#!/bin/bash
#

if [ -x /etc/rc.d/rc.grub_image ]; then
  /etc/rc.d/rc.grub_image
fi

Para terminar, faça-os executáveis e reinicie o sistema. Mas antes de reiniciar é sempre bom dar uma boa olhada da seções do seu grub.cfg e verificar se está tudo correto, pois seu sistema pode não iniciar corretamente, caso a partição indicada, ou o kernel estiverem incorretos.