06 - Initramfs - Initrd (Sistema de Arquivos Temporário)
video: https://youtu.be/... no frontmatter da nota.O ecossistema de inicialização do kernel Linux enfrenta um paradoxo arquitetural clássico, frequentemente chamado de problema "do ovo e da galinha". Para que o kernel possa montar o sistema de arquivos raiz (/), ele necessita dos device drivers adequados para interagir com o controlador de armazenamento físico (SATA, NVMe, SCSI), bem como de módulos lógicos de mapeamento de blocos (LVM, RAID via mdadm, multipath) e camadas de criptografia (LUKS/dm-crypt). Contudo, a imensa maioria desses módulos e binários reside exatamente dentro do sistema de arquivos raiz que ainda não foi montado (em /lib/modules/).
Para solucionar essa dependência circular cíclica sem inchar o binário do kernel (vmlinuz) com drivers estáticos infindáveis, a arquitetura do Linux introduziu o conceito de um sistema de arquivos temporário injetado diretamente na memória RAM pelo bootloader. Este ambiente efêmero serve exclusivamente para fornecer as ferramentas espaciais do usuário e os módulos de núcleo mínimos necessários para localizar, desbloquear, montar e transitar para o sistema de arquivos raiz definitivo.
Ao longo do desenvolvimento do Linux, este mecanismo evoluiu drasticamente, dividindo-se em duas implementações arquiteturalmente distintas: o legado initrd e o moderno initramfs.
1. Initrd (Initial RAM Disk): A Abordagem Legada
O initrd foi a primeira solução implementada para o problema de montagem da raiz. Embora o termo ainda seja coloquialmente utilizado de forma intercambiável com initramfs, do ponto de vista do Ring 0, suas mecânicas são obsoletas e estruturalmente ineficientes.
1.1. Arquitetura em Bloco e Falsificação de Dispositivo
No esquema initrd, o arquivo gerado e passado pelo bootloader é uma imagem literal de um sistema de arquivos completo (frequentemente ext2 ou cramfs), que muitas vezes é comprimida com gzip.
Quando o kernel recebe essa imagem, ele precisa instanciar um dispositivo de bloco virtual em memória (o ramdisk, tipicamente /dev/ram0). A imagem comprimida é então descompactada para dentro desse dispositivo de bloco de tamanho fixo.
1.2. Problemas Arquiteturais do Initrd
- Desperdício de Memória e Tamanho Fixo: O
ramdiskrequer a alocação de um bloco contíguo e de tamanho fixo na memória. Se oramdisktem 15MB e os arquivos ocupam apenas 5MB, 10MB de RAM estão permanentemente desperdiçados. - Duplo Cache (Double Caching): Como o
initrdemula um dispositivo de bloco real, todas as leituras feitas nele passam pelo subsistema de cache de páginas do kernel (Page Cache). O VFS (Virtual File System) lê os dados doramdisk(que já está na RAM) e os coloca em um cache na própria RAM, duplicando o consumo de memória para os mesmos dados. - Overhead de Sistema de Arquivos: Para ler os arquivos, o kernel precisa de um driver de sistema de arquivos completo (como o
ext2) embutido estaticamente no binário monolítico, adicionando complexidade e peso ao núcleo básico. - pivot_root: A transição do
initrdpara a raiz real exigia o uso da chamada de sistemapivot_root. Esta syscall literalmente troca a montagem raiz atual por uma nova, movendo a raiz antiga para um subdiretório (como/initrd), o que exigia a desmontagem manual posterior, um processo propenso a vazamentos de memória e bloqueios de inodes.
2. Initramfs (Initial RAM Filesystem): O Padrão Moderno
Para mitigar o overhead do initrd, o desenvolvimento do kernel 2.6 introduziu o initramfs. O initramfs não é um dispositivo de bloco emulado; ele é uma instância nativa do tmpfs (ou ramfs), uma camada que mapeia arquivos diretamente nas estruturas de cache de página e de dentries do VFS, dispensando totalmente a camada de blocos.
2.1. O Formato cpio
Em vez de formatar um arquivo como um sistema de arquivos ext2, o initramfs é simplesmente um arquivo comprimido do tipo cpio (Copy In, Copy Out). A escolha do cpio (especificamente o formato SVR4 newc) não é acidental:
- É um formato contínuo (streamable), o que significa que o kernel pode processar e extrair seus arquivos linearmente em uma única passagem de leitura, sem precisar pular setores.
- O descompactador e extrator de
cpioé microscópico em termos de código (algumas centenas de linhas em C) e está profundamente incorporado ao código de inicialização do VFS (init/initramfs.c).
2.2. Vantagens Arquiteturais
- Redimensionamento Dinâmico: Um
tmpfsnão tem tamanho fixo inicial. Ele cresce dinamicamente na RAM à medida que os arquivos docpiosão extraídos, e encolhe instantaneamente quando os arquivos são apagados, eliminando o desperdício de memória. - Zero Double Caching: Os arquivos no
initramfsnão passam pela camada de bloco (struct bio). Eles são instanciados diretamente nos caches nativos do kernel. - Ausência de Drivers Adicionais: Como não há formatação geométrica, o kernel não precisa de drivers estáticos de
ext2,fatouxfspara conseguir realizar o primeiro boot.
3. O Fluxo de Execução no Ambiente Initramfs
A mecânica de inicialização envolvendo o initramfs segue um pipeline altamente rigoroso e sequencial.
3.1. Hand-off do Bootloader e Descompressão
- O bootloader (como o GRUB2) aloca dois blocos na RAM: um para o
vmlinuz(kernel) e outro para o arquivoinitramfs.img. Os endereços de memória físicos de ambos são passados ao kernel. - O kernel inicializa seu gerenciador de memória (MMU), processadores (SMP) e aloca a estrutura especial do VFS chamada
rootfs. - O kernel invoca a função
populate_rootfs(), que identifica a compressão (GZIP, LZ4, ZSTD), descompacta o buffer de memória e extrai os inodes e dados viacpiopara dentro dorootfsvazio.
3.2. O PID 1 Temporário (/init)
O kernel então busca por um arquivo executável nomeado /init na raiz deste rootfs efêmero. Este script ou binário torna-se o PID 1 temporário. O trabalho do /init é complexo e vital:
- Montagem de Subsistemas: Ele imediatamente monta pseudo-sistemas de arquivos vitais:
/proc,/syse/dev. - Descoberta de Hardware: Aciona gerenciadores como o
udevd(ou omdevem sistemas embarcados) para varrer a árvore de dispositivos em/sys/devices, ler os identificadores (ex:MODALIAS) e criar dinamicamente os nós de dispositivo em/dev(ex:/dev/sda1). - Injeção de Módulos: Baseado nas descobertas do passo anterior, utiliza o
modprobepara injetar os arquivos.kocontidos no próprio initramfs (dentro de/usr/lib/modules/) para dentro do Ring 0. - Construção de Mídia Lógica: Se o sistema usa LVM, o
/initexecutavgchange -aypara ativar os Volume Groups. Se usar LUKS, solicita a senha do usuário viacryptsetuppara mapear o dispositivo descriptografado em/dev/mapper/. - Montagem da Raiz Final: Com o dispositivo de bloco exposto e o driver de sistema de arquivos (ex:
ext4,xfs) carregado, o script/initmonta a raiz definitiva do disco físico de forma apenas-leitura (read-only) em um diretório de transição, tipicamente/sysroot.
3.3. Transição: switch_root
Aqui reside a diferença final entre o obsoleto initrd e o initramfs. O rootfs base no kernel Linux é uma estrutura "imortal" — ele não pode ser desmontado (umount), pois é a âncora do VFS.
Para transferir a execução, o utilitário switch_root é invocado. Ele realiza uma operação de terra arrasada:
- Ele recursivamente deleta todos os arquivos, diretórios e symlinks de dentro do
initramfsativo na RAM para liberar a memória física. - Ele executa a syscall de montagem para mover a montagem de
/sysrootpor cima da própria raiz (/). Orootfsoriginal ainda existe arquiteturalmente, mas fica permanentemente ocluso (escondido sob a nova montagem). - Ele executa uma chamada
exec()para transferir o PID 1 para o/sbin/initreal (ousystemd) do novo disco. Como a transição usaexec, o novo processo de inicialização herda o PID 1 exato, finalizando a fase efêmera.
4. Estruturação Modular Moderna
Hoje, a construção de imagens initramfs não é feita de forma estática, mas orientada a módulos e perfis de hardware hospedeiro, através de geradores dinâmicos como Dracut (Red Hat/Fedora), mkinitcpio (Arch Linux) ou update-initramfs (Debian/Ubuntu).
Essas ferramentas permitem ao administrador especificar exatamente quais binários (como fsck e mdadm), arquivos de configuração (como fstab) e drivers (através do mapeamento do lsmod atual ou da flag --hostonly) devem ser encapsulados na imagem cpio.
Falhas na construção ou na leitura desta imagem pelo bootloader frequentemente resultam em paradas severas, sendo a origem mais comum da incapacidade de montagem, resultando na queda do ambiente para o console de recuperação (shell busybox interativo acionado pelo /init quando o /sysroot falha ao montar), aguardando intervenção manual direta do administrador do sistema para corrigir partições, arranjos lógicos ou tabelas de mapeamento corrompidas.