Nos tempos antigos, o kernel era codificado para conhecer o número principal / menor do dispositivo, os fs raiz e o montou depois de inicializar todos os drivers de dispositivo que foram incorporados ao kernel. O rdev
utilitário pode ser usado para modificar o número do dispositivo raiz na imagem do kernel sem precisar recompilar.
Eventualmente, os carregadores de inicialização apareceram e poderiam passar uma linha de comando para o kernel. Se o root=
argumento foi passado, isso informava ao kernel onde estava o root fs, em vez do valor incorporado. Os drivers precisavam acessar o que ainda precisava ser incorporado ao kernel. Embora o argumento pareça um nó de dispositivo normal no /dev
diretório, obviamente não existe um /dev
diretório antes da montagem do root fs, portanto o kernel não pode procurar um nó de desenvolvimento lá. Em vez disso, certos nomes de dispositivos conhecidos são codificados no kernel para 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
um UUID de volume.
Mais tarde, o initrd
entrou em cena. Junto com o kernel, o carregador de inicialização carregava a initrd
imagem, que era algum tipo de imagem do sistema de arquivos compactada (imagem ext2 compactada com gzip, imagem romfs compactada com gzip, squashfs finalmente se tornou dominante). O kernel descompactaria essa imagem em um ramdisk e montaria o ramdisk como o root fs. Esta imagem continha alguns drivers adicionais e scripts de inicialização, em vez de reais init
. Esses scripts de inicialização executavam várias tarefas para reconhecer hardware, ativar coisas como matrizes de ataque e LVM, detectar UUIDs e analisar a linha de comando do kernel para encontrar a raiz real, que agora poderia ser especificada por UUID, rótulo de volume e outras coisas avançadas. Em seguida, montou o fs raiz real /initrd
e executou a pivot_root
chamada do sistema para trocar o kernel /
e/initrd
, em seguida, exec /sbin/init
na raiz real, que desmontaria /initrd
e liberaria o ramdisk.
Finalmente, hoje temos o initramfs
. Isso é semelhante ao initrd
, mas em vez de ser uma imagem do sistema de arquivos compactada carregada em um ramdisk, é um arquivo cpio compactado. Um tmpfs é montado como raiz e o arquivo é extraído lá. Em vez de usar pivot_root
, que era considerado um hack sujo, os initramfs
scripts de inicialização montam a raiz real /root
, excluem todos os arquivos na raiz tmpfs, depois chroot
no /root
e exec /sbin/init
.