Como o Linux carrega a imagem 'initrd'?

12

Estou tentando entender o processo de inicialização, mas há apenas uma coisa que está passando pela minha cabeça ...

As soon as the Linux kernel has been booted and the root file system (/) mounted, programs can be run and further kernel modules can be integrated to provide additional functions. To mount the root file system, certain conditions must be met. The kernel needs the corresponding drivers to access the device on which the root file system is located (especially SCSI drivers). The kernel must also contain the code needed to read the file system (ext2, reiserfs, romfs, etc.). It is also conceivable that the root file system is already encrypted. In this case, a password is needed to mount the file system.

The initial ramdisk (also called initdisk or initrd) solves precisely the problems described above. The Linux kernel provides an option of having a small file system loaded to a RAM disk and running programs there before the actual root file system is mounted. The loading of initrd is handled by the boot loader (GRUB, LILO, etc.). Boot loaders only need BIOS routines to load data from the boot medium. If the boot loader is able to load the kernel, it can also load the initial ramdisk. Special drivers are not required.

Se / boot não é uma partição diferente, mas está presente na partição /, então o carregador de inicialização não deve exigir que os drivers SCSI acessem a imagem 'initrd' e a imagem do kernel? Se você pode acessar as imagens diretamente, então por que exatamente precisamos dos drivers SCSI?

    
por Nighpher 09.09.2013 / 10:32

3 respostas

19
Nighpher, tentarei responder à sua pergunta, mas para uma descrição mais abrangente do processo de inicialização, tente Artigo da IBM .

Ok, eu suponho que você esteja usando o GRUB ou o GRUB2 como seu bootloader para explicação. Em primeiro lugar, quando a BIOS acessa seu disco para carregar o gerenciador de inicialização, ele faz uso de suas rotinas internas para acesso ao disco, que são armazenadas na famosa interrupção de 13 horas. Bootloader (e kernel na fase de instalação) fazem uso dessas rotinas quando acessam o disco. Observe que o BIOS é executado no modo real (16 bits) do processador, portanto, ele não pode endereçar mais de 2 ^ 20 bytes de RAM (2 ^ 20 não 2 ^ 16 porque cada endereço em modo real é composto por segment_address * 16 + offset , onde o endereço do segmento e o deslocamento são de 16 bits, consulte link ). Assim, essas rotinas não podem acessar mais de 1 MiB de RAM, o que é uma limitação estrita e um grande inconveniente.

O BIOS carrega o código do bootloader diretamente do MBR - os primeiros 512 bytes do seu disco e o executa. Se você estiver usando o GRUB, esse código será o estágio 1 do GRUB. Esse código carrega o estágio 1.5 do GRUB, localizado nos primeiros 32 KiB de espaço em disco, chamado região de compatibilidade do DOS ou de um endereço fixo do sistema de arquivos. Ele não precisa entender o sistema de arquivos para fazer isso, porque mesmo o estágio 1.5 está no sistema de arquivos, é um código "bruto" e pode ser carregado diretamente na RAM e executado: link . A carga do stage1.5 do disco para a RAM faz uso das rotinas de acesso ao disco da BIOS.

OStage1.5contémosutilitáriosdosistemadearquivos,paraqueelepossalerostage2dosistemadearquivos(bem,eleaindausaoBIOS13hparalerdodiscoparaaRAM,masagorapodedecifrarinformaçõesdosistemadearquivossobreinodesetc.foradodisco).BiosmaisantigospodemnãosercapazesdeacessaroHDinteirodevidoalimitaçõesnomododeendereçamentodedisco-elespodemusarosistemaCylinder-Head-Sector,incapazdeendereçarmaisdoque8GBdeespaçoemdisco: link .

O Stage2 carrega o kernel na RAM (novamente, usando os utilitários de disco do BIOS). Se é kernel 2.6+, também tem o initramfs compilado, portanto não há necessidade de carregá-lo. Se for um kernel antigo, o bootloader também carrega imagens initrd independentes na memória, para que o kernel possa montá-lo e obter drivers para montar o sistema de arquivos real a partir do disco.

O problema é que o kernel (e o ramdisk) pesa mais de 1 MiB, para carregá-los na RAM você tem que carregar o kernel no primeiro 1 MiB, então pular para o modo protegido (32 bits), mover o kernel carregado para alto memória (libere o primeiro 1 MiB para o modo real), retorne ao modo real (16 bits) novamente, obtenha o ramdisk do disco para o primeiro 1 MiB (se for um kernel initrd e antigo separado), possivelmente mude para protegido (32 bits) modo de novo, coloque-o onde ele pertence, possivelmente voltar ao modo real (ou não: link ) e execute o código do kernel. Aviso: Não tenho certeza absoluta sobre a exatidão e exatidão dessa parte da descrição.

Agora, quando você finalmente executa o kernel, você já o tem e o ramdisk é carregado na RAM pelo bootloader , então o kernel pode usar utilitários de disco do ramdisk para montar seu sistema de arquivos raiz e pivot root isto. Os drivers ramfs estão presentes no kernel, então ele pode entender o conteúdo do initramfs, é claro.

    
por 09.09.2013 / 11:51
1

Acredito que tudo se resume a quais recursos o gerenciador de inicialização específico suporta. Por exemplo. ele não precisa conhecer o sistema de arquivos específico de sua partição combinada (boot + root). Nesse caso, basta criar uma partição de inicialização separada, na condição de que ela funcione com o seu gerenciador de inicialização, e qualquer outra complexidade de como montar sua partição raiz é deixada no kernel e a inicialização da imagem a partir da partição de inicialização. O Bootloader sabe como acessar os dispositivos SCSI (e outros dispositivos também, dependendo de qual bootloader é usado) usando seus próprios drivers ou utilizando rotinas de BIOS. Além disso, sabe ler alguns sistemas de arquivos, etc.

Considere por exemplo. Forma de UEFI de inicialização, onde, na verdade firmware UEFI já sabe como acessar a partição EFI, lê-lo e carregar o kernel do Linux a partir daí sem necessidade de bootloader intermediário. Nesse caso, a imagem do Linux permanece separada da partição raiz e o firmware UEFI não precisa conhecer todos os sistemas de arquivos exóticos para acessá-la. Acredito que a separação das imagens de "boot" da partição "root" faz muito sentido. Se não for para mais nada, então é necessário configurar a criptografia do sistema de arquivos raiz.

    
por 09.09.2013 / 12:27
0

Apenas para o registro, se um bootloader não carregar o initrd, vale a pena testar outro gerenciador de inicialização; Acabei de me deparar com uma situação como isso quando o LILO silenciosamente ignorou um initrd de tamanho médio especificado corretamente (< 4Mb; rootfs ext4 único em um SSD SATA; GPT) e o GRUB 2.00 teve êxito.

O processo de inicialização terminou rapidamente com um típico

RAMDISK: Couldn't find valid RAM disk image starting at 0.
Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(8,3)
    
por 30.01.2017 / 19:19