initrd e Sistemas de Arquivos em RAM Disk
Um initrd (initial ramdisk) é uma pequena imagem de sistema de arquivos carregada inteiramente em memória antes de o kernel montar seu sistema de arquivos raiz de verdade, resolvendo um problema de dependência circular que Multiboot e Physical Memory já mencionam módulos e um ramdisk sem explicar por que um é necessário: o driver do sistema de arquivos raiz real (um driver AHCI, por exemplo) pode ele mesmo depender de módulos ou firmware que só existem dentro desse mesmo sistema de arquivos raiz, uma dependência circular sem forma alguma de se resolver a partir de um início frio.
O problema que o initrd resolve
Seção intitulada “O problema que o initrd resolve”Um kernel construído com todo driver linkado estaticamente evita esse problema por completo, mas ao custo de um binário grande e inflexível que precisa ser reconstruído para qualquer mudança de hardware; um kernel que em vez disso carrega drivers como módulos separados a partir de seu sistema de arquivos raiz, um design comum e consideravelmente mais flexível, esbarra diretamente na circularidade: não consegue montar o sistema de arquivos raiz sem o driver de armazenamento, e não consegue carregar o driver de armazenamento sem antes ter acesso ao sistema de arquivos onde o arquivo de módulo desse driver vive. O mesmo problema aparece sempre que algum requisito de boot inicial (descriptografar um volume raiz criptografado, montar um array RAID por software, ou simplesmente escolher qual entre vários dispositivos raiz disponíveis de fato usar) precisa de código ou configuração que de outra forma teria que viver exatamente no volume ao qual esse requisito está bloqueando o acesso.
Quebrando o ciclo com um ramdisk
Seção intitulada “Quebrando o ciclo com um ramdisk”Um initrd quebra esse ciclo nunca dependendo do driver do próprio sistema de arquivos raiz final: o bootloader carrega uma pequena imagem de sistema de arquivos como um módulo Multiboot diretamente na memória ao lado do próprio kernel, antes de o kernel ter rodado uma única instrução, e o kernel monta essa imagem a partir da RAM usando um driver de sistema de arquivos simples o suficiente para não ter dependências externas próprias (um formato mínimo somente leitura, ou até um formato de arquivo não comprimido como cpio, em vez de um sistema de arquivos completo). Como a imagem já está sentada na memória, alcançável da mesma forma que qualquer outra estrutura de dados de tempo de boot, montá-la não precisa de driver de armazenamento algum, enumeração PCI alguma, nem I/O de tipo algum além de ler memória que já está ali.
// simplificado: localiza o módulo que o bootloader já carregoustruct multiboot_module *mod = &mb_info->modules[0];void *initrd_start = (void *)mod->mod_start;size_t initrd_size = mod->mod_end - mod->mod_start;
mount_ramdisk(initrd_start, initrd_size);Com o initrd montado, o kernel agora tem um sistema de arquivos, por mais mínimo que seja, de onde carregar o módulo do driver de armazenamento real, junto com qualquer outra coisa que o boot inicial precise (blobs de firmware, uma ferramenta de montagem de RAID, um prompt de chave de descriptografia) que de outra forma seria inalcançável. Uma vez que esse driver real está carregado e inicializado, e o sistema de arquivos raiz real que ele gerencia pode ser montado, o kernel realiza um pivot root (ou switch root): o sistema de arquivos real assume como /, e o ramdisk temporário, seu trabalho terminado, tipicamente é descartado ou desmontado por completo em vez de persistir ao lado da raiz real.
Notas de implementação
Seção intitulada “Notas de implementação”O próprio formato de sistema de arquivos de um initrd é deliberadamente mantido simples, já que seu driver precisa estar construído diretamente no kernel sem dependência alguma de qualquer coisa que o próprio initrd de outra forma forneceria, um problema de dependência circular de boot inicial um nível acima do que o initrd resolve para a raiz real; um arquivo cpio comprimido (o formato initramfs) ou uma imagem mínima somente leitura são ambas escolhas comuns especificamente porque um driver para qualquer um dos dois é pequeno o suficiente para justificar linkagem permanente no binário do kernel em vez de carregamento como módulo. O próprio passo de pivot/switch root, tratado uma vez que o sistema de arquivos real está disponível, é exatamente o tipo de operação que a abstração de montagem da camada VFS é construída para suportar: da perspectiva de um chamador, a raiz da árvore de sistema de arquivos simplesmente passa a apontar para um sistema de arquivos montado diferente, sem que nada acima da VFS precise de lógica de caso especial pelo fato de um initrd tê-la precedido.
Referências
Seção intitulada “Referências”- ^ The Linux Kernel Documentation, initrd: Initial RAM disk: descreve o papel em tempo de boot e o mecanismo de carregamento aos quais a formulação geral do problema deste artigo se aplica amplamente, além da implementação específica do Linux.