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

03 - Criação e Recriação (dracut, mkinitcpio, update-initramfs)

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

A imagem do initramfs não é um artefato estático distribuído de forma universal pelos desenvolvedores do kernel. Devido à vasta heterogeneidade de topologias de hardware, arranjos lógicos de armazenamento (LVM, LUKS, RAID) e arquiteturas de rede, o ambiente de espaço de usuário precoce deve ser compilado e empacotado dinamicamente no próprio sistema hospedeiro. Este processo de geração atua como uma ponte de introspecção: a ferramenta geradora examina o estado atual do sistema operacional em execução (ou de um ambiente em chroot), resolve cadeias de dependências de bibliotecas dinâmicas e módulos de kernel, e empacota um arquivo cpio customizado.

As três principais infraestruturas arquiteturais que dominam o ecossistema Linux para esta tarefa são update-initramfs (Debian/Ubuntu), dracut (Red Hat/Fedora/SUSE) e mkinitcpio (Arch Linux). Embora o objetivo final seja o mesmo, a filosofia de resolução de dependências e a estrutura de módulos (hooks) diferem radicalmente entre elas.

1. O Desafio da Resolução de Dependências

Antes de analisar as ferramentas individuais, é vital compreender a complexidade da geração do initramfs. O gerador não pode simplesmente copiar o binário do cryptsetup ou do mdadm para a imagem cpio. No Linux, binários em espaço de usuário dependem de bibliotecas compartilhadas (arquivos .so como libc.so, libpthread.so, libdevmapper.so).

Durante o processo de criação, a ferramenta utiliza utilitários como ldd (List Dynamic Dependencies) para rastrear a árvore de vinculação dinâmica de cada binário requisitado. O gerador extrai recursivamente todas as bibliotecas necessárias e as posiciona sob as réplicas de /lib e /lib64 no diretório de compilação temporário, garantindo que nenhum binário sofra um erro de segmentation fault por falta de símbolos durante a inicialização (quando o disco real ainda não está montado).

Da mesma forma, ao identificar a necessidade de um módulo de kernel (ex: ext4.ko), o gerador deve invocar modprobe --show-depends para garantir que dependências ocultas (como crc16.ko ou mbcache.ko) sejam incluídas simultaneamente.

2. A Família Debian/Ubuntu: update-initramfs e mkinitramfs

No ecossistema Debian, o comando de alto nível é o update-initramfs, que atua como um wrapper para o script backend mkinitramfs. A arquitetura baseia-se fortemente em diretórios de hooks (ganchos de compilação) e scripts de tempo de execução (ganchos de boot).

2.1. Comportamento e Configuração (initramfs.conf)

A configuração central reside em /etc/initramfs-tools/initramfs.conf. A diretiva mais crítica neste arquivo é a variável MODULES, que define a heurística de inclusão de drivers de hardware:

  • MODULES=most: É o padrão tolerante a falhas. O mkinitramfs varre /lib/modules/ e inclui praticamente todos os drivers de controladoras de disco, USB, rede e sistemas de arquivos. O resultado é um initramfs volumoso (frequentemente >50MB), mas altamente portátil (o disco pode ser fisicamente movido para outra placa-mãe de chipset diferente e o sistema fará o boot perfeitamente).
  • MODULES=dep: Modo restrito. O script interroga o sysfs (através do /sys/devices/) e o udev para mapear exclusivamente o hardware atualmente responsável por hospedar a raiz (/). O initramfs gerado é minúsculo (otimizando tempo de boot e uso de RAM), mas perde completamente a portabilidade de hardware.

2.2. A Arquitetura de Hooks e Scripts

O mkinitramfs possui dois diretórios vitais em /usr/share/initramfs-tools/ (e seus correspondentes para o usuário em /etc/initramfs-tools/):

  • /hooks/: Scripts executados durante a geração da imagem. Um hook típico (ex: lvm2) contém lógica em bash que diz ao gerador: "Se o sistema usa LVM, copie o binário /sbin/lvm e todas as suas bibliotecas .so para a pasta temporária de compilação do cpio".
  • /scripts/: Scripts copiados para **dentro da imagem cpio** e executados pelo /init durante o processo de boot. Eles são categorizados em estágios estritos: init-top, init-premount (onde ferramentas como o cryptsetup geralmente atuam), local-top, local-bottom e init-bottom.

3. A Família RHEL/Fedora/SUSE: O Paradigma dracut

O dracut é uma ferramenta de geração de segunda geração, projetada para substituir o antigo mkinitrd. Diferente de seus pares que dependem de lógicas lineares e fortemente codificadas, o dracut é uma estrutura modular baseada em eventos (event-driven), operando em extrema simbiose com o systemd e o udev.

3.1. A Lógica de Hostonly

O dracut introduziu a flag --hostonly (padrão em distribuições modernas da família Red Hat). Quando ativada, o dracut não adivinha o hardware. Ele varre o /proc/mounts, o arquivo /etc/fstab, e os block devices atuais via lsblk interno, e constrói um perfil cirúrgico do que é estritamente necessário para montar este sistema específico. Se o / estiver em um Volume Lógico (LV) sobre um arranjo MDRAID, o dracut embutirá apenas as regras de udev pertinentes àqueles UUIDs específicos, descartando todo o resto.

3.2. Módulos do Dracut (modules.d)

A espinha dorsal do dracut reside em /usr/lib/dracut/modules.d/. Cada subdiretório (como 90crypt, 90mdraid, 98systemd) é um módulo autônomo contendo três elementos principais:

  • module-setup.sh: O script executado na geração. Ele define funções cruciais como check() (para verificar se o módulo deve ser ativado baseado no ambiente hospedeiro), depends() (para invocar módulos pré-requisitos do próprio dracut) e install() (onde o comando interno inst ou inst_multiple resolve dependências de arquivos e bibliotecas e os injeta na imagem em memória).
  • Regras do Udev: O dracut frequentemente copia regras cruciais de /usr/lib/udev/rules.d/ para dentro do initramfs, permitindo que a detecção de dispositivos no boot seja gerenciada de forma assíncrona, não travando o pipeline de inicialização enquanto aguarda timeouts de hardware rotacionais.

A execução manual para regeneração total para o kernel atual tipicamente assume a forma: dracut --force --hostonly /boot/initramfs-$(uname -r).img $(uname -r).

4. A Família Arch Linux: mkinitcpio

O mkinitcpio reflete a filosofia de simplicidade e transparência de projeto do Arch Linux. É um script shell altamente legível que oferece controle granular absoluto ao administrador, abdicando do isolamento arquitetural complexo presente no dracut em favor de uma matriz determinística de geração.

4.1. O Arquivo de Configuração Principal e a Array HOOKS

A espinha dorsal do comportamento do mkinitcpio é o arquivo /etc/mkinitcpio.conf. A variável mais importante é o array bash HOOKS=(). A ordem exata na qual os hooks são declarados neste array define o comportamento cronológico tanto da geração da imagem quanto do sequenciamento lógico durante o boot.

Um exemplo típico de array de hooks:
HOOKS=(base udev autodetect keyboard keymap modconf block encrypt lvm2 filesystems fsck)

O funcionamento deste array expõe uma mecânica avançada de filtragem:

  • O hook base instala o busybox e o próprio script de inicialização do initramfs.
  • O hook udev injeta o daemon systemd-udevd para descoberta genérica de dispositivos.
  • O hook autodetect é a característica mais engenhosa. Ele inspeciona o hardware atual e atua como um filtro temporal dinâmico para os hooks que o sucedem. Se declarado antes do hook block ou keyboard, o autodetect restringe a inclusão de drivers de teclado e armazenamento estritamente àqueles identificados no hardware presente (semelhante ao --hostonly do dracut). Se o administrador desejar criar um pendrive de boot universal (portátil), ele simplesmente remove o hook autodetect do array.
  • O hook block insere os módulos de SCSI, SATA, NVMe, etc. Se filtrado pelo autodetect, inclui apenas os módulos necessários.
  • Os hooks de abstração lógica, como encrypt e lvm2, devem obedecer a um sequenciamento rigoroso: devem estar declarados após block (pois precisam do disco físico reconhecido) e antes de filesystems (pois o driver de arquivo ext4 ou btrfs precisa que o bloco lógico já esteja descriptografado e mapeado em /dev/mapper/).

4.2. Geração Baseada em Presets

No ecossistema Arch, a chamada manual via mkinitcpio -g /caminho.img é rara. O padrão é a utilização do diretório /etc/mkinitcpio.d/, que abriga arquivos .preset. Um preset (como linux.preset) define múltiplos perfis de geração automática por kernel instalado. Por padrão, ele orienta a ferramenta a construir sempre duas imagens simultâneas a cada atualização de kernel (acionado via pacman hooks):

  1. default: Utilizando as restrições do hook autodetect para máxima performance.
  2. fallback: Uma imagem secundária massiva, que instrui o parser a ignorar temporariamente o hook autodetect, englobando todo e qualquer módulo de barramento disponível. Esta imagem serve como um seguro de vida, garantindo a inicialização do sistema caso haja migração abrupta de placa-mãe ou corrupção na detecção do barramento PCIe primário.