Como um kernel Linux é capaz de acessar o initramfs / initrd atribuído?

8

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

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

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 e memória do sistema? Entendo que a tarefa do Grub é "carregar e executar o kernel" e possui seu próprio conjunto de módulos para acessar arquivos em dispositivos (ou rede) para acessá-los. No exemplo, aqui insmodestá s, set roote search- mas isso é apenas da perspectiva do Grub, e não é compartilhado com o kernel, certo?

Também estou supondo que o Grub esteja carregando (uma cópia?) Do kernel na memória ( linuxcomando ) e chutando-o para iniciar a execução. (aparentemente duas etapas diferentes - então, como?) Os parâmetros fornecidos podem ser lidos no kernel e interpretados (esta é uma grande string mapeada na memória em algum lugar?) e fornece as opções para organizar as coisas solicitadas.

Eu também vejo essa initrdopção. Isso aponta para o meu initramfs compactado com gzip, necessário para inicializar o dispositivo raiz real especificado por root=. Mas como esse initramfs é fornecido ao kernel? Não é passado nenhum endereço de memória para onde ele pode carregá-lo, nem é possível acessá-lo, pois ele já está carregado antes do início do kernel. Alguma documentação do kernel diz que esse 'dispositivo' do sistema de arquivos initramfs pode ser acessado /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, eu não vejo, eu acho.

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

Apenas para esclarecer minhas perguntas, acho que entendo por que os diferentes estágios de inicialização existem e quais transições ocorrem, mas não vejo como eles ocorrem 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 se resume.

Eu apreciaria alguma explicação sobre isso.

gertvdijk
fonte
Observe o bootcomando implícito no final da sequência. Não sei exatamente o que ele faz no Grub, mas se você usar a linha de comando do Grub para inserir esses comandos manualmente, precisará bootou ele ficará para sempre grub>(ou pelo menos até que você fique entediado e desligue o computador) ) Os comandos anteriores "meramente" configuram um ambiente.
um CVn
@ MichaelKjörling Pelo que entendi agora, boota CPU saltará para o endereço do kernel carregado (iniciar a execução). Para uma entrada de menu, isso é definido implicitamente. veja isso .
Gdvdijk

Respostas:

5

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

Como isso depende do hardware (arm é diferente de x86, por exemplo), você precisa encontrar as informações corretas, consulte este artigo sobre a inicialização do arm ou o protocolo de inicialização Linux / x86 para obter alguns exemplos.

Ulrich Dangel
fonte
6

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

jsbillings
fonte
Eu cheguei tão longe; mas como o carregador de inicialização informa o kernel sobre a localização na memória? Onde o kernel recupera esse endereço de memória?
gertvdijk
3
@gertvdijk dê uma olhada em kernel.org/doc/Documentation/x86/boot.txt e descreve como o gerenciador de inicialização se comunica com o kernel, ou seja, o gerenciador de inicialização também precisa fornecer os parâmetros do kernel etc.
precisa
@UlrichDangel Nice! Exatamente o que eu estava procurando. Aparentemente, é um protocolo específico de hardware (x86 neste caso) que descreve tudo. Escreva como resposta com uma breve descrição e eu aceito.
gertvdijk