Initrd

Em computação (especificamente no que diz respeito ao Linux), o initrd (initial ramdisk, em português disco RAM inicial) é um esquema para carregar um sistema de arquivos raiz temporário na memória, que pode ser usado como parte do processo de inicialização do Linux. initrd e initramfs se referem a dois métodos diferentes de se conseguir isso. Ambos são comumente usados para fazer os preparativos antes que o sistema de arquivos raiz real possa ser montado.[1]

Explicação

O sistema operativo GNU/Linux, ao igual que outros sistemas Unix, consiste num núcleo, Linux, que é carregado inicialmente em memória, e que permanece de maneira residente durante o funcionamento do sistema, bem como aplicativos — software que se executa no espaço de utente, baixo o controle do núcleo.

Para minimizar a quantidade de código que se carrega em memória, e para uma modularidade máxima, o núcleo Linux ignora muito código necessário para carregar o sistema operativo. Parte deste código encontra-se em módulos do núcleo, enquanto o resto são aplicativos no espaço de utente.

Para realizar um sistema de arranque que possa servir para hardware variado, ou que possa ser carregado a partir de diferentes meios incluindo meios virtuais e transitórios como os previstos por uma conexão de rede, costuma ser necessário para o núcleo aceder ao espaço de utente e quiçá a módulos do núcleo de maneira que possa obter os dados e rotinas necessárias para aceder ao armazém de dados principal. Não tem por que ocorrer com todas as possíveis configurações, ainda que costuma se dar o caso.

O sistema de arranque initrd tem sido a principal solução a este problema desde há muito tempo , ainda que o recentemente desenvolvido initramfs introduzido no núcleo Linux 2.6 contém importantes melhorias.

No sistema initrd, os arquivos que precisam ser acedidos pelo núcleo durante o arranque se alojam num disco RAM, cujos conteúdos se encontram num sistema de arquivos sobre um arquivo montado como um dispositivo de bucle, ou mais historicamente, num pequeno dispositivo montável como um disquette, e ocupa geralmente entre 1,4 MB e 4 MB. O sistema de arquivos está comprimido com gzip. A localização da imagem deste disco RAM dá-se ao núcleo na carga pelo carregador de arranque (geralmente ou LILO ou GRUB).

O sistema initrd emprega certos "truques" e tem alguns inconvenientes, desde o ponto de vista de um administrador. Criar ou editar uma imagem de um sistema de arquivos de um disco RAM requer mordomias de administrador para montar a imagem do sistema de arquivos para realizar mudanças, e/ou para inicializar a estrutura do sistema de arquivos (dar formato) no dispositivo virtual. Ademais, o sistema de arquivos utilizado na imagem do disco RAM deve ser um que não se vá utilizar no núcleo, e o código para aceder ao sistema de arquivos deve estar programado no núcleo, o que implica que não pode ser descarregado mais adiante da mesma maneira que se pode fazer quando o código é carregado a partir de módulos do núcleo.

Os discos RAM são de tamanho fixo, pelo que costumam utilizar mais espaço do necessário, e também limitam a quantidade de espaço de trabalho disponível uma vez que o sistema está arrancado. Aliás o enfoque de initrd não permite descarregar nada da memória utilizada por este sem reiniciar.

No entanto, pese a estes problemas, dado que desde faz anos o sistema veio-se utilizando quase de forma universal, ainda tem um amplo uso.

Initramfs em comparação com initrd

Em comparação, initramfs é um sistema mais conveniente e simples para gerir pelos administradores que os sistemas prévios baseados em discos RAM, já que o código externo alojado no disco RAM inicial pode ser editado facilmente sem mordomias de administrador, e já que há uma menor indireção: não há necessidade de fazer um disco virtual, ou formatar e prover ao núcleo com capacidade para manejar sistemas de arquivos para além dos requisitos mínimos para ler um arquivo cpio comprimido.

Desde que o sistema original baseado em discos RAM se popularizou, um novo sistema de arquivos baseado em memória RAM mais flexível, conhecido como tmpfs ou shmfs, se converteu num componente regular do núcleo. Este sistema é bem mais flexível e eficiente que o disco RAM de tamanho fixo original em muitos aspectos: não requer formato, e utiliza tanta memória como se precise para conter os dados.

Também se usava outro sistema similar, ramfs, que dá ao sistema initramfs seu nome. Actualmente os utentes podem eleger que sistema de arquivos dinâmico em RAM utilizar.[2]

Além do código para tmpfs, que se utiliza no núcleo para quase todas as configurações de Linux, o único requisito para fazer um disco virtual desde o que arrancar era acrescentar a possibilidade de descompactar um pacote de arquivos (os desenvolvedores do núcleo escolheram utilizar o formato de arquivo cpio). Os arquivos descompactados alojam-se num sistema de arquivos parecido a tmpfs. Este sistema conhece-se como initramfs.[3]

Usos

Bem como para carregar o código necessário para preparar o arranque do sistema, um disco RAM (já seja initrd ou initramfs) pode ser útil como disco de resgate, para utilizar em actualizações de segurança, cópias de segurança de arquivos, realizar análises forenses, depurar problemas de hardware, ou obviar um disco duro, por exemplo para arrancar imagens do sistema operativo por rede ou desde um médio lento como um CD-ROM.

Muitas distribuições Linux levam uma única imagem genérica do núcleo destinada a arrancar na maior variedade possível de hardware. Os controladores incluídos com esta imagem genérica do núcleo devem ser modulares, já que não é possível compilar todo de forma estática no núcleo sem o fazer demasiado grande para arrancar em computadores com pouca memória ou desde meios de baixa capacidade como disquettes.

Isto a sua vez implica o problema de detectar e carregar os módulos necessários para montar o sistema de arquivos raiz no arranque (ou deduzir que sistema de arquivos é ou onde se encontra).

Para complicar ainda mais as coisas, o sistema de arquivos raiz pode estar num volume RAID por software, LVM, um sistema de arquivos por rede de algum tipo (NFS é comum em computadores sem discos) ou numa partição criptografada. Todos eles requerem preparações especiais para montar.

Implementação

A imagem do núcleo e a do initrd, devem ser guardadas em algum lugar acessível pelo firmware de arranque do computador ou o software de arranque, como por exemplo Grub. Em PC, isto é geralmente:

  • O sistema de arquivos raiz em si.
  • Uma pequena partição formatada como FAT ou ext2 no disco local (uma partição de arranque).
  • Um servidor TFTP (em sistemas que possam arrancar desde Ethernet).

O carregador de arranque carregará em memória o núcleo e a imagem initrd, e depois executará o núcleo, passando a direcção de cor do initrd. Ao final de sua sequência de arranque, o núcleo tenta determinar o formato da imagem de seus primeiros blocos de dados:

  • Esquema ramfs: Se a imagem é uma imagem de um sistema de arquivos (opcionalmente comprimida com gzip), então fáz-se-á disponível como um dispositivo de bloco especial (/dev/ram), que montar-se-á como o sistema de arquivos raiz inicial. O controlador para esse sistema de arquivos deve ser compilado estaticamente no núcleo. Muitas distribuições usavam originalmente sistemas de arquivos ext2 comprimidos como imagens initrd. Outras (incluindo Debian 3.1), usavam cramfs para arrancar em sistemas com memória limitada, já que a imagem cramfs pode ser montada sem requerer espaço adicional para descompressão.
Uma vez que este sistema de arquivos raiz está iniciado, o núcleo executa "/linuxrc" como seu primeiro processo. Quando termina, o núcleo assume que o sistema de arquivos real tem sido montado no mesmo lugar e executa "/sbin/init" para começar o processo de arranque normal em "espaço do utente".
  • Esquema initram: Se a imagem é um arquivo cpio comprimido com gzip, será desempaquetada pelo núcleo num passo intermediário a um tmpfs, que depois se converte no sistema de arquivos raiz inicial. A este esquema chamou-se-lhe initramfs e está disponível desde Linux 2.6.13 em adiante. Tem a vantagem de não requerer que um sistema de arquivos intermediários seja compilado no núcleo.
Com initramfs, o núcleo executa "/init" como seu primeiro processo. "/init" não se espera que termine.

Algumas distribuições de GNU/Linux, geram um initrd personalizado que consiste só nas partes necessárias para arrancar esse computador em particular, como módulos do núcleo para ATA, SCSI e sistemas de arquivos. Estes tipicamente incluem a localização e o tipo do sistema de arquivos raiz.

Outras, como Fedora e Ubuntu, criam um initrd mas genérico. Estas começam só com o nome do dispositivo do sistema de arquivos raiz (ou sua UUID) e devem descobrir todo o demais no momento do arranque. Neste caso, uma complexa sucessão de tarefas deve realizar-se para conseguir montar o sistema de arquivos raiz:

  • Qualquer controlador do que dependa o processo de arranque deve ser carregado. Uma solução comum é empacotar os módulos do núcleo para os dispositivos de armazenamento comuns no initrd e depois invocar o agente de hotplug para carregar os módulos adequados para o hardware do computador detectado.
  • Se o sistema de arquivos raiz está em NFS:
    • Iniciar a interface de rede primária.
    • Invocar um cliente DHCP, com o que possa obter uma direcção.
    • Extrair a direcção do servidor NFS da resposta DHCP.
    • Montar o diretório compartilhado.
  • Se o sistema de arquivos raiz está num dispositivo RAID por software, "/linuxrc" não tem forma de saber em que dispositivo do volume RAID está, e deve invocar as utilidades regular MD para procurar todos os dispositivos de bloco disponíveis e iniciar o correcto.
  • Se o sistema de arquivos raiz está num volume lógico, "/linuxrc" deve invocar as utilidades LVM para procurar e activar o grupo de volumes que o contém.
  • Se o sistema de arquivos raiz esta num dispositivo de blocos criptografado, "/linuxrc" deve:
    • Invocar o script ajudante para consultar ao utente sobre a chave e/ou inserir o hardware requerido, como uma Smart Card ou um dongle USB.
    • Criar um destino de decifrado com o mapeador de dispositivos.
  • Executar qualquer tarefa de manutenção que não possa ser feita de forma segura num sistema de arquivos já montado como raiz.
  • Montar o sistema de arquivos em modo somente leitura.

O sistema de arquivos raiz final não pode se montar sobre "/", já que isso deixaria os scripts e as ferramentas no sistema de arquivo raiz inicial inaccessível para qualquer tarefa de limpeza final. Em seu lugar é montado num ponto de montagem temporária e alterado para seu lugar com pivot_root(2) (que foi introduzido especificamente para este propósito). Isto deixa o sistema raiz inicial num ponto de montagem (como "/initrd") onde os scripts de início normal podem posteriormente o desmontar para libertar memória ocupada pelo initrd.

A maioria dos sistemas de arquivos raiz implementam "/linuxrc" ou "/init" como um script de shell e portanto incluem um shell mínimo (usualmente /bin/ash) junto com outras utilidades essenciais (usualmente Busybox). Para poupar um pouco mais de espaço, a shell, as utilidades e suas bibliotecas necessárias usualmente são compiladas com optimizações de espaço habilitadas (como por exemplo a opção de gcc -Vos) e enlaçadas contra versões reduzidas da biblioteca de C como dietlibc ou klibc.

Algumas distribuições (notavelmente SUSE e Ubuntu) ademais usam o initrd para mostrar uma imagem gráfica durante o processo de arranque.

Ver também

Referências

  1. Landley, Rob (15 de março de 2005). «Introducing initramfs, a new model for initial RAM disks». linuxdevices.com. Consultado em 4 de março de 2016. Arquivado do original em 1 de março de 2009 
  2. «initramfs: Allow rootfs to use tmpfs instead of ramfs». 30 de julho de 2006 
  3. «Re: initramfs: Allow rootfs to use tmpfs instead of ramfs». 31 de julho de 2006 

Ligações externas