Como um bootloader é transferido para um kernel?

3

Suponha que eu tenha um bootloader com uma linha kernel e initrd . Para todos os efeitos, agora tenho 2 ou 3 estágios de "kernel" acontecendo:

  1. firmware
  2. grub (ou outro bootloader)
  3. kernel real do linux

O acima seria para o MBR. Para EFI, o bootloader (ou bootmanager) é apenas um aplicativo EFI que é executado enquanto o firmware é o "kernel":

  1. firmware, carrega o aplicativo EFI
  2. kernel real do linux

Qual é o processo real de transferência do kernel? O que o MBR grub realmente faz para ir de 2 a 3, ou o firmware EFI para ir de 1 a 2? É semelhante a kexec ?

Segundo, no caso do EFI, onde alguns ganchos são passados para o aplicativo EFI e daí para o kernel do Linux (para que possamos fazer coisas como efibootmgr, etc.), como isso é passado?

Finalmente, é possível fazer isso mais de uma vez? Por exemplo. se eu tiver algum trabalho personalizado que preciso fazer antes de carregar meu sistema operacional "normal", por exemplo, medindo e validando entradas de TPM, descriptografia, etc., talvez coisas que não são facilmente feitas usando grub, rEFInd ou outros, eu poderia carregar um kernel de estágio "provisório" e initrd, fazê-las, e então entregar?

    
por deitch 04.04.2016 / 23:04

1 resposta

2

Algumas notas, principalmente em sistemas BIOS / GRUB.

Sistema BIOS com GRUB:

Início da BIOS em endereço 0xfffffff0 (x86).

Faça vários testes, por exemplo POSTAR. Se tudo correr bem, verifique os dispositivos, na ordem configurada e salva no CMOS. O primeiro dispositivo de inicialização que possui um MBR válido, (a assinatura no deslocamento 510 é 0x55aa ), é carregado na memória no endereço 0x7c00 .

Em seguida, o BIOS deixa o controle para o código (bytes) que é carregado a partir do MBR no deslocamento 0 . Isso é; os dados em que o controle é deixado devem ser instruções do processador. Um programa.

Por exemplo, se você olhar para uma imagem MBR, provavelmente encontrará algo como eb6390 no começo. Isso se traduz em duas instruções de máquina:

eb63 => jump to 0x63 (offset 0x65 in MBR as count is from end of instruction)
90   => No Operation
  • boot.S na origem do GRUB. Primeiras instruções no MBR na montagem:

    jmp LOCAL(after_BPB)
    nop
    

A partir daqui, o GRUB carrega a próxima etapa. Tipicamente primeiro setor de core.img

  • diskboot.S na origem do GRUB em uma inicialização normal do disco.

Um salto é feito para este código, que então carrega o restante de core.img . Isto inclui, por exemplo, correcção de erros Reed-Solomon, descompressão, etc. %código%. O GRUB atual é baseado em módulos e estes também são carregados neste estágio.

Os arquivos de configuração do GRUB são lidos, e quando ele determina qual kernel deve ser executado, ele o carrega do diretório startup_raw.S para a memória. Em seguida, a imagem de disco RAM inicial, /boot , é carregada na memória.

O gerenciador de partida também grava o endereço de memória das strings de configuração no espaço de memória dos kernels. Ou seja opções de inicialização. Consulte campos de cabeçalho marcados "modificar" .

Observe também que o carregador de boot normalmente alterna entre o modo real e o modo protegido durante o estágio de carregamento. Isso para poder carregar dados além do limite de 1 MB.

Quando isso é feito, o gerenciador de partida deixa o controle no kernel, assim como o BIOS deixou o controle no gerenciador de inicialização através do MBR. Isso é feito em modo real.

O kernel é (geralmente) baseado em módulos. Entre os módulos estão, por exemplo, módulos do sistema de arquivos. Na inicialização, o kernel provavelmente tem que ler arquivos de um sistema de arquivos que precisa de um módulo para ler… é aqui que o initrd entra em ação. Os módulos necessários para começar residem aqui.

(U) EFI :

O processo de inicialização (U) EFI pode ir muito na mesma trilha que o BIOS / GRUB se usar uma instalação do uefigrub, etc. Também há a opção de usar o EFI Boot Stub , que permite que o firmware EFI carregue o kernel como um executável EFI.

Além disso, a partir do kernel 3.14 , initrd também está disponível, mas não se destina a inicialização a frio.

    
por 05.04.2016 / 04:13