Home Comunidade Eventos YouTube Networks Desafios // produtos Academy News CTI | CVE Contato

02 - Arquivo de Configuração (grub.cfg)

video explicativo
Video explicativoEspaco reservado para o video desta anotação — adicione video: https://youtu.be/... no frontmatter da nota.

1. A Natureza Dinâmica e o Paradigma de Scripting

Diferente do GRUB Legacy (versão 0.9x), que utilizava um arquivo de texto estático e simples (menu.lst) focado em mapeamento direto de discos, o GRUB2 introduziu o grub.cfg. Este arquivo não é um mero dicionário de apontamentos; ele é, na realidade, um script interpretável escrito em uma linguagem de domínio específico (Domain-Specific Language - DSL) quase Turing-completa, que implementa um subconjunto rigoroso das sintaxes do bash padrão (POSIX sh).

Quando o microkernel do GRUB2 transita para o Estágio 2 e lê o grub.cfg, ele ativa um interpretador interno capaz de:

  • Declarar, interpolar e exportar variáveis de ambiente.

  • Avaliar blocos condicionais (if, then, elif, else, fi).

  • Executar laços de repetição e funções parametrizadas.

  • Tratar saídas de comandos e códigos de retorno (exit status).

Essa complexidade permite que o bootloader tome decisões em tempo real durante a inicialização do hardware, como carregar drivers de vídeo específicos apenas se a plataforma for UEFI, ou ajustar o tempo de espera (timeout) se a inicialização anterior falhou.

2. A Cadeia de Geração e o Princípio da Intocabilidade

A primeira e mais crítica regra arquitetural do GRUB2 é: o arquivo /boot/grub/grub.cfg nunca deve ser editado manualmente pelo administrador humano. O próprio cabeçalho do arquivo contém um aviso expresso gerado automaticamente.

O grub.cfg é o produto final de um processo de compilação (build pipeline) orquestrado pelo utilitário grub-mkconfig (frequentemente com alias para update-grub em distribuições baseadas em Debian). Este utilitário constrói o arquivo final concatenando o processamento de duas fontes distintas do espaço do usuário:

I. O Arquivo de Variáveis: /etc/default/grub

Este é o ponto de interação primário do administrador. É um arquivo de configuração do tipo chave-valor (key-value) interpretado pelo shell. Ele define o comportamento global do bootloader:

  • GRUB_DEFAULT: Define qual entrada será inicializada por padrão (pode ser um índice numérico ou a string "saved" para lembrar a última escolha).

  • GRUB_TIMEOUT: O tempo em segundos que o menu aguardará por intervenção antes de aplicar o padrão.

  • GRUB_CMDLINE_LINUX: Parâmetros que serão injetados incondicionalmente no kernel.

  • GRUB_TERMINAL: Define se o output será em console serial ou gráfico.

II. O Diretório de Scripts de Execução: /etc/grub.d/

Este diretório contém uma série de scripts de shell executáveis, numerados sequencialmente para garantir a ordem de processamento (de 00 a 99). Quando grub-mkconfig é invocado, ele executa cada um destes scripts:

  • 00_header: Lê as variáveis de /etc/default/grub e traduz para as variáveis de ambiente internas do GRUB2, além de carregar os módulos de vídeo e criptografia essenciais.

  • 10_linux: Varre o diretório /boot/ em busca de binários do kernel (vmlinuz-*) e arquivos initramfs, gerando automaticamente os blocos menuentry para o sistema operacional principal.

  • 20_linux_xen: Similar ao anterior, mas arquitetado para localizar hipervisores Xen.

  • 30_os-prober: Executa o utilitário os-prober que monta temporariamente todas as outras partições do disco para detectar instalações de Windows, macOS ou outras distribuições Linux, injetando suas entradas de chainloading no grub.cfg.

  • 40_custom e 41_custom: Arquivos vazios deixados propositalmente para o administrador inserir scripts manuais que não serão sobrescritos pelas atualizações do sistema.

O output gerado (em stdout) por toda essa cadeia é redirecionado para o arquivo final /boot/grub/grub.cfg.

3. Anatomia Estrutural: Diretivas Globais e Módulos

As primeiras seções do grub.cfg gerado configuram o ambiente global. É neste estágio que o GRUB2 injeta seus módulos sob demanda via comando insmod.

Bash

set timeout=5
load_video
insmod gzio
insmod part_gpt
insmod ext2

A diretiva load_video é frequentemente uma chamada de função (definida internamente pelo GRUB) que avalia a plataforma de hardware para carregar efi_gop (sob UEFI) ou vbe (sob BIOS).

Em seguida, o interpretador obriga a carga da biblioteca de descompressão gzio (necessária para ler o kernel), o módulo de reconhecimento de tabelas GPT (part_gpt) e o driver do sistema de arquivos raiz (ext2, que também serve para ext3 e ext4).

O Comando search e o Desacoplamento Lógico

Uma das maiores inovações arquiteturais visíveis no grub.cfg é o abandono da fiação física direta. No passado, o bootloader apontava para algo como /dev/sda1. Se um disco extra fosse adicionado, a topologia mudava para /dev/sdb1 e o sistema falhava ao inicializar.

O GRUB2 resolve isso com o comando dinâmico search:

Bash

search --no-floppy --fs-uuid --set=root 1234abcd-56ef-78gh-90ij-klmnopqrstuv

Ao executar esta linha, o GRUB2 varre todos os dispositivos de bloco disponíveis em busca de uma assinatura exata de UUID de sistema de arquivos. Quando encontra, ele atrela esse dispositivo lógico à variável interna root do GRUB2. A partir deste ponto, caminhos relativos como /boot/vmlinuz são lidos diretamente desta partição mapeada dinamicamente, garantindo resiliência absoluta contra mudanças na ordem física das portas SATA ou NVMe.

4. O Bloco Operacional: menuentry e submenu

A essência funcional do grub.cfg reside nos blocos menuentry. Cada bloco descreve um sistema operacional bootável ou uma ferramenta de diagnóstico e define a sequência lógica que o GRUB2 deve executar se o usuário selecionar essa opção no menu.

A estrutura anatômica de um menuentry para o Kernel Linux é rigorosa:

Bash

menuentry 'Debian GNU/Linux' --class debian --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-uuid-...' {
    load_video
    insmod gzio
    if [ x$grub_platform = xxen ]; then insmod xzio; insmod lzopio; fi
    insmod part_gpt
    insmod ext2
    search --no-floppy --fs-uuid --set=root 1234abcd-...
    echo    'Loading Linux 6.1.0-9-amd64 ...'
    linux   /boot/vmlinuz-6.1.0-9-amd64 root=UUID=5678efgh-... ro quiet
    echo    'Loading initial ramdisk ...'
    initrd  /boot/initrd.img-6.1.0-9-amd64
}

O Paradoxo do Root: GRUB Root vs Kernel Root

Neste bloco, é vital compreender a distinção entre dois conceitos que frequentemente causam confusão arquitetural profunda:

  1. O root do GRUB (variável interna): Definido pelo comando search --set=root. Ele indica ao GRUB2 onde ler fisicamente os binários do kernel e do initramfs. Ele aponta para a partição /boot.

  2. O parâmetro root= do Kernel: Injetado como texto puro na diretiva linux. Ele diz ao Kernel Linux (após o GRUB2 morrer) qual dispositivo deve ser montado como a árvore de diretórios raiz / principal do sistema operacional.

(A análise profunda dos comandos linux e initrd, bem como a comunicação do bootloader com o kernel, será exaurida na nota focada em Passagem de Parâmetros).

Para evitar a poluição visual de dezenas de versões de kernels antigos no menu principal, o grub.cfg implementa a diretiva submenu. Trata-se de um encapsulamento de menuentries. Quando selecionado, o GRUB invoca um novo contexto de exibição, limpando a tela e exibindo apenas os itens aninhados, criando uma árvore de navegação hierárquica.

5. Segurança Direta no grub.cfg: PBKDF2 e Controle de Acesso

O grub.cfg também atua como a primeira linha de defesa contra invasões de hardware local. Se o bootloader não for protegido, qualquer pessoa com acesso físico ao teclado pode pressionar a tecla e no menu do GRUB, editar o bloco menuentry para injetar init=/bin/bash na linha do kernel e obter acesso root irrevogável (modo monousuário irrestrito) sem precisar de senha.

Para mitigar isso, o grub.cfg suporta o controle de acesso nativo baseado em usuários e senhas hasheadas.

O administrador executa o utilitário grub-mkpasswd-pbkdf2 para gerar um hash forte baseado em Password-Based Key Derivation Function 2. O resultado é injetado através de arquivos em /etc/grub.d/ para gerar o seguinte código no grub.cfg:

Bash

set superusers="admin"
password_pbkdf2 admin grub.pbkdf2.sha512.10000.E8F...

Uma vez que superusers é declarado, o GRUB2 bloqueia o interpretador de comandos e a edição dinâmica (teclas c e e no menu). Somente após o usuário inserir as credenciais corretas (autenticadas contra a string PBKDF2), o GRUB2 desbloqueia o menu, garantindo a integridade de boot estabelecida pela política do arquivo de configuração.