Como um kernel Linux é capaz de acessar seu initramfs / initrd designado?

7

Estou tentando entender o processo de inicialização de uma máquina como um todo desde o momento em que você aperta o botão liga / desliga. Há uma parte do bootloader para o estágio initramfs que eu não entendo muito bem entre alguns outros bits menores.

Dada esta configuração do Grub para uma entrada, tirada de uma instalação padrão do Ubuntu recente:

insmod gzio
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set=root 96fb7310-5adb-4f66-bf59-04acd08d76a3
echo    'Loading Linux x.y.z ...'
linux   /vmlinuz-x.y.z root=/dev/mapper/some-device-name ro nomodeset 
echo    'Loading initial ramdisk ...'
initrd  /initrd.img-x.y.z

O que isso realmente faz em termos de estado do sistema e memória? Eu entendo que a tarefa do Grub é "carregar e executar o kernel" e tem seu próprio conjunto de módulos para acessar arquivos em dispositivos (ou rede) para acessá-los. No exemplo aqui insmod s, set root e search - mas isso é apenas da perspectiva do Grub, e não é compartilhado com o kernel, certo?

Eu também estou supondo que o Grub está carregando (uma cópia?) do kernel na memória ( linux command ) e chutando-o para iniciar a execução. (dois passos diferentes aparentemente - então, como?) Os parâmetros dados podem ser lidos no kernel e interpretados (isso é uma grande string mapeada na memória em algum lugar?) e fornecer as opções para organizar as coisas solicitadas.

Eu também vejo essa opção initrd . Isso aponta para o initramfs compactado por gzip, necessário para inicializar o dispositivo raiz real especificado por root= . Mas como este initramfs é fornecido ao kernel? Não é passado nenhum endereço de memória para onde ele possa carregá-lo, nem é capaz de acessá-lo, já que ele já está carregado antes do kernel ser iniciado. Algumas documentações do kernel dizem que o 'dispositivo' do sistema de arquivos initramfs está acessível por /dev/ram0 , mas não vejo como ele se torna um arquivo de dispositivo acessível para começar. Há algo acontecendo debaixo d'água que eu não vejo, eu acho.

Eu também não vejo como isso se relaciona com outros carregadores de inicialização, incluindo plataformas embarcadas, por exemplo, usando U-boot / Coreboot. Isso está fazendo a mesma coisa que o Grub (mesmo endereço de memória padrão?) E até que ponto eles se comparam ao Grub em relação ao carregamento do kernel / initrd?

Só para esclarecer minhas dúvidas, acho que entendo por que os diferentes estágios de inicialização existem e quais transições ocorrem, mas não vejo como eles acontecer e quais são as responsabilidades exatas para cada um dos estágios. Tenho a sensação de que estou perdendo algum "padrão" ao qual tudo isso se resume.

Eu gostaria de receber algumas explicações sobre isso.

    
por gertvdijk 18.12.2012 / 18:16

2 respostas

5

Em geral, tem que haver algum tipo de protocolo, porque normalmente não basta apenas carregar um arquivo na memória e pular em um local específico, mas você precisa passar argumentos adicionais, como parâmetros do kernel, ou seja, acessando os argumentos do memdisk do DOS .

Como isso é dependente de hardware (arm é diferente de x86 por exemplo) você tem que encontrar a informação correta, veja este artigo sobre o booting arm ou o o protocolo de boot do Linux / x86 para alguns exemplos.

    
por 19.12.2012 / 00:10
5

O bootloader armazena o initrd em um local na memória e informa ao kernel o endereço de memória da imagem initrd. A maioria dos sistemas Linux modernos usa o esquema initramfs usando dracut , que é na verdade um arquivo cpio (ao invés de uma imagem de disco) que é descompactado em um sistema de arquivos tmpfs criado pelo kernel logo após a execução.

    
por 18.12.2012 / 20:22