Nos tempos antigos, o kernel era codificado para saber o número principal / secundário do dispositivo do root fs e montá-lo depois de inicializar todos os drivers de dispositivo, que foram embutidos no kernel. O utilitário rdev
poderia ser usado para modificar o número do dispositivo raiz na imagem do kernel sem ter que recompilá-lo.
Eventualmente, os carregadores de boot apareceram e puderam passar uma linha de comando para o kernel. Se o argumento root=
foi passado, isso disse ao kernel onde a raiz fs estava em vez do valor interno. Os drivers necessários para o acesso ainda precisavam ser incorporados ao kernel. Embora o argumento pareça um nó de dispositivo normal no diretório /dev
, obviamente não há diretório /dev
antes de a raiz fs ser montada, portanto, o kernel não pode procurar um nó dev lá. Em vez disso, determinados nomes de dispositivos conhecidos são codificados para o kernel, de modo que a string possa ser traduzida para o número do dispositivo. Por causa disso, o kernel pode reconhecer coisas como /dev/sda1
, mas não coisas mais exóticas como /dev/mapper/vg0-root
ou um volume UUID.
Mais tarde, o initrd
entrou na foto. Juntamente com o kernel, o gerenciador de partida carregaria a imagem initrd
, que era algum tipo de imagem do sistema de arquivos compactado (imagem ext2 gzipada, imagem romfs gzipada, squashfs finalmente se tornou dominante). O kernel iria descompactar esta imagem em um ramdisk e montar o ramdisk como root fs. Esta imagem continha alguns drivers adicionais e scripts de inicialização em vez de um init
real. Esses scripts de inicialização executaram várias tarefas para reconhecer hardware, ativar itens como raid arrays e LVM, detectar UUIDs e analisar a linha de comando do kernel para encontrar a raiz real, que agora poderia ser especificada pelo UUID, rótulo de volume e outros itens avançados. Em seguida, montou a raiz real fs em /initrd
e, em seguida, executou a chamada de sistema pivot_root
para que o kernel trocasse /
e /initrd
, depois exec /sbin/init
na raiz real, o que desmontaria /initrd
e libere o ramdisk.
Finalmente, hoje temos o initramfs
. Isso é semelhante ao initrd
, mas em vez de ser uma imagem do sistema de arquivos compactado que é carregada em um ramdisk, ele é um arquivo compactado do cpio. Um tmpfs é montado como a raiz e o arquivo é extraído lá. Em vez de usar pivot_root
, que era considerado um hack sujo, os scripts de inicialização initramfs
montam a raiz real em /root
, excluem todos os arquivos na raiz tmpfs, então chroot
em /root
e exec /sbin/init
.