Como o Linux lida com uma partição separada / de inicialização?

11

Estou interessado em aprender como o Linux lida com partições de inicialização separadas. Na verdade, não estou interessado em fazer isso, mas gostaria de saber como isso funciona.

Considere um disco rígido sda, que possui duas partições sda1e sda2. Digamos que sda2é a rootpartição /que contém o sistema operacional Linux.

Meu entendimento é que o gerenciador de inicialização GRUB2está montado no /boot. Quando o diretório /bootestá em uma partição separada sda2, no entanto, como é que isso pode acontecer antes de /ser realmente montado?

Como a interação entre o BIOS, o registro de inicialização mestre e o GRUB (ou os arquivos /boot) ocorre com êxito nesse caso? Será que os dados /bootnão estão realmente montados no /sistema de arquivos nesse estágio inicial?

Nota: esta pergunta trata da montagem da partição raiz, mas não discute uma partição de inicialização separada.

jII
fonte

Respostas:

18

Aqui está o problema em sua compreensão:

Meu entendimento é que o carregador de inicialização GRUB2 está montado em / boot.

O GRUB não está "montado" na inicialização. GRUB é instalado para /boot, e é carregado a partir do código no Master Boot Record. Aqui está uma visão geral simplificada do processo de inicialização moderno, assumindo uma distribuição GNU / Linux com um MBR / BIOS (não GPT / UEFI):

  1. O BIOS é carregado.
  2. O BIOS carrega o pequeno pedaço de código que está no registro mestre de inicialização.
  3. O GRUB não cabe em 440 bytes, o tamanho do Registro de Inicialização Mestre. Portanto, o código carregado na verdade apenas analisa a tabela de partição, localiza a /bootpartição (que acredito ser determinada quando você instala o GRUB no registro de inicialização mestre) e analisa as informações do sistema de arquivos. Em seguida, ele carrega o GRUB do Estágio 2. (É aqui que entra a simplificação.)
  4. O GRUB do estágio 2 carrega tudo o que precisa, incluindo a configuração do GRUB, e apresenta um menu (ou não, dependendo da configuração do usuário).
  5. Uma sequência de inicialização é escolhida. Isso pode ocorrer por um tempo limite, pelo usuário selecionando uma entrada de menu ou inicializando uma lista de comandos.
  6. A sequência de inicialização começa a executar. Isso pode fazer várias coisas - por exemplo, carregar um kernel, carregar em cadeia para outro carregador de inicialização - mas vamos supor que a sequência de inicialização seja o GNU / Linux padrão.
  7. O GRUB carrega o kernel do Linux.
  8. O GRUB carrega o ramdisk inicial .
  9. O ramdisk inicial é montado /em /new_root(possivelmente desbloqueado criptograficamente), inicia o udev, inicia o resumo da troca, etc.
  10. O ramdisk inicial usa o pivot_rootutilitário para definir /new_rootcomo o real /.
  11. initcomeça. As partições são montadas, os daemons são iniciados e o sistema é inicializado.

Observe como o kernel é carregado apenas na etapa 7. Por causa disso, não há conceito de montagem até a etapa 7 . É por isso /bootque deve ser montado novamente na etapa 9, mesmo que o GRUB já o tenha usado.

Também pode ser útil consultar a seção GRUB 2 da página da Wikipedia no GRUB.

strugee
fonte
Você deteve minha confusão exatamente. Isto é exatamente o que eu estava procurando. Então, inicialmente, /bootnão está se referindo a um diretório montado na partição raiz?
jii
@jesterII awesome! nesse caso, você se importaria em aceitar esta resposta clicando na marca de seleção logo abaixo das setas de votação?
strugee
7
O código MBR não pode analisar um sistema de arquivos. Ele carrega a imagem do núcleo do grub dos setores não utilizados após o MBR antes da primeira partição, e esse código entende como encontrar e montar a partição / boot para encontrar os arquivos de configuração do grub, módulos adicionais e seus kernels. O pivot_root também foi considerado um hack sujo e foi substituído pelo run-initque exclui todos os arquivos no initramfs e, em seguida, chroots no sistema de arquivos raiz.
Psusi
Processo de inicialização moderna deve ser agora processo de inicialização legado como UEFIcada vez mais mais e mais popurlar ;-) @strugee
kiwy
1
@strugee, após discussão na lista de util-linux, parece que minha lembrança estava um pouco desanimada: eles pararam de permitir pivot_root nos rootfs reais, e é por isso que ninguém mais o usa durante a inicialização. No entanto, o Systemd o usa no desligamento, para não retornar ao initrd original (que se remove ao mudar para a raiz real), mas para mudar para uma nova carregada. Veja marc.info/?l=util-linux-ng&m=139100788306216&w=2
psusi
6

Questão 1

Meu entendimento é que o carregador de inicialização GRUB2 está montado em / boot. Quando o diretório / boot está em uma partição separada sda2, no entanto, como é que isso pode acontecer antes / na verdade é montado?

Eu não acho que você esteja entendendo bem aqui. Na página da Wikipedia do GNU GRUB :

excerto

Quando um computador é ligado, o BIOS do computador localiza o dispositivo inicializável primário configurado (geralmente o disco rígido do computador), carrega e executa o programa inicial de autoinicialização a partir do registro mestre de inicialização (MBR). O MBR é o primeiro setor do disco rígido e tem o número 0 (a contagem de setores começa em 0). Por um longo tempo, o tamanho de um setor é de 512 bytes, mas desde 2009 existem discos rígidos disponíveis com um tamanho de setor de 4096 bytes, chamados de discos de formato avançado . Em outubro de 2013, esses discos rígidos ainda são acessados ​​em setores de 512 bytes, utilizando a emulação 512e .

Na versão 2 do GRUB, ocorre o seguinte:

excerto

Inicializando o computador

Quando a energia é ligada, acontece o seguinte:

  • O hardware inicializa, define a CPU para o modo real (sem memória virtual) e salta para o local fixo 0xFFFF0 (conectado nos circuitos da CPU)
  • O código do BIOS armazenado em uma ROM ou memória flash mapeada para esse local é, portanto, executado.
  • O código do BIOS examina os dados de configuração do BIOS para ver qual é o dispositivo de inicialização. Esses dados de configuração do BIOS geralmente podem ser editados pressionando uma sequência de teclas especial logo após ligar a alimentação, causando a execução do programa de configuração do BIOS. Entre outras coisas, o dispositivo de inicialização geralmente pode ser selecionado aqui.
  • O código do BIOS carrega o MBR do dispositivo de inicialização na RAM. Lembre-se de que um MBR tem apenas 512 bytes! Os dados carregados são, é claro, o programa e os dados que o grub-install criaram e criaram dinamicamente quando o programa grub-install foi executado.
  • O código do BIOS salta para o endereço inicial do MBR carregado (ou seja, o código Grub é executado pela primeira vez desde a inicialização).
  • O código MBR do Grub carrega um único setor cujo endereço está conectado no bloco MBR. Em seguida, circula os pares (endereço, len) nesse setor, carregando todos os dados do disco na memória (ou seja, carrega o conteúdo do arquivo /boot/grub/core.imgou sua cópia "incorporada"). O código MBR então salta para o código carregado, ou seja, "executa" o programa core.img.
  • Conforme descrito na seção “Instalando o Grub”, esse truque de incorporar os endereços de bloco de disco bruto permite armazenar core.imgno espaço que não está em uma partição e que nunca foi formatado como um sistema de arquivos (“incorporação”). E, nesse caso, se core.imgfor modificado, desde que a nova versão seja "incorporada" no mesmo local, o código MBR não precisará ser atualizado.
  • Como alternativa, é possível core.imgque ele esteja dentro de um sistema de arquivos real e que o Grub leia o core.imgconteúdo do arquivo sem ter um driver para esse sistema de arquivos. No entanto, nesse caso, se core.imgfor modificado, o primeiro bloco do arquivo poderá receber um novo endereço no disco; se isso acontecer, o MBR deverá ser atualizado para apontar para esse novo local. No entanto, como core.imggeralmente é atualizado executando o grub-install, isso geralmente não é um problema.
  • Observe que teoricamente, se core.imgestiver em um dispositivo diferente do MBR, e novo hardware for adicionado, o registro MBR gerado pelo Grub poderá não conseguir carregar corretamente o core.imgarquivo; o ID do dispositivo no qual o primeiro setor core.imgdeve ser encontrado é conectado ao MBR, não pesquisado. No entanto, não há solução para isso; não há como incorporar o equivalente do comando Grub “search” no MBR de 512 bytes. Esse problema não é provável; normalmente o core.imgé incorporado no mesmo dispositivo que o MBR. E uma vez core.imgcarregado, ele pode usar o search.mod para encontrar todos os outros /boot/grubarquivos e, portanto, é imune a reorganizações de hardware.
  • O core.imgcódigo executado agora inicializa todos os módulos nele construídos (vinculados core.img); um desses módulos será um driver de sistema de arquivos capaz de ler o sistema de arquivos no qual o diretório /boot/grubestá localizado.
  • Ele também registra um conjunto de comandos internos: set, unset, ls, insmod.
  • Se um "arquivo de configuração" tiver sido vinculado core.img, ele será passado para um analisador de script embutido muito simples para processamento. Os comandos de script no arquivo de configuração podem chamar apenas comandos internos ou vinculados. Cenários simples (por exemplo, inicializando um computador desktop típico a partir de uma unidade local) não precisam de um arquivo de configuração; esse recurso é usado para coisas como inicialização via pxe, nfs remotos ou quando /boot/grubestiver em um dispositivo LVM.
  • Core.imgagora carrega o arquivo “/boot/grub/normal.mod”dinamicamente do disco e salta para sua função de entrada. Observe que esta etapa requer a instalação do driver do sistema de arquivos apropriado (isto é, embutido).

     ss do processo de inicialização

NOTA: Quando você vê o menu típico do GRUB2 em que seleciona qual OS / Kernel inicializar, está fazendo referência ao /boot/grubdiretório do sistema neste momento.

                                         ss do grub tui

Referências

slm
fonte
Alguém deve corrigir essa entrada da Wikipedia, porque está errada. O estágio 1 / 1.5 / 2 é aplicável apenas ao grub herdado. Eles foram completamente eliminados na reescrita do grub2 e você não encontrará nenhuma referência a esses termos na documentação oficial do grub 2.
Psusi
@psusi - obrigado por esclarecer. Fiquei um pouco confuso quando os vi mencionados lá também, já que ouvi o mesmo, que 1 / 1.5 / 2 se foi. Eu não saberia a quem pedir para editar artigos da Wikipedia, não me sentiria qualificado para editar uma publicação desse tipo. Talvez alertar a equipe do GRUB2 seria a próxima melhor coisa?
slm
@ psusi - aqui está a ref. a estágios sendo eliminados em off. docs para GRUB2: gnu.org/software/grub/manual/grub.html ... "Os arquivos de imagem (consulte Imagens) que compõem o GRUB foram reorganizados; as etapas 1, 2 e 2 não são mais."
slm
6

O Linux (o kernel) não se importa com quantas partições de inicialização você possui. Carregar o kernel do disco é o trabalho do bootloader (por exemplo grub, grub2, lilo) e essas ferramentas também não se preocupam com o número de locais um kernel pode ser localizado. Eles se preocupam apenas com o local específico.

Como exemplo, minha partição de inicialização é /dev/md1, que é um espelho RAID mdadm suportado pelas partições físicas /dev/sde1e /dev/sdf1. Eu posso montá-los individualmente, se quiser, e, como tal, tecnicamente conta como tendo duas partições de inicialização, embora elas devam conter os mesmos dados.

Ter duas partições para / boot para mim é um problema de disponibilidade, mas elas podem ser igualmente diferentes / partições de inicialização. O próximo passo é como o gerenciador de inicialização sabe? Aqui está como:

menuentry 'Linux 3.10.17 (sde) kernel-3.10.17-g' {
        root=hd0,1
        linux /boot/kernel-3.10.17-g domdadm dolvm root=/dev/md3
        initrd /boot/initrd-3.10.17-g
}

menuentry 'Linux 3.10.17 (sdf) kernel-3.10.17-g' {
        root=hd1,1
        linux /boot/kernel-3.10.17-g domdadm dolvm root=/dev/md3 
        initrd /boot/initrd-3.10.17-g
}

Este é um trecho de uma grub2configuração e você notará que as únicas diferenças são root=hd0,1e root=hd1,1que estabelecem qual partição de inicialização que a entrada faz referência.


Agora, você será guiado por uma bota para que você possa entender o que está acontecendo aqui.

  • O BIOS lê o MBR do volume de inicialização e salta para o carregador de inicialização
  • O gerenciador de inicialização (por exemplo grub2) está configurado para saber qual dispositivo e partição contém seu kernel. O Grub2 acessa essa partição diretamente e carrega seu kernel na memória.
  • Seu carregador de inicialização então salta para o kernel e o kernel inicializa sua máquina.

O carregador de inicialização não se importa com quantas partições de inicialização você possui, apenas se importa onde elas estão e você deve informar essas informações.

O kernel não se importa com quantas partições de inicialização você possui, porque nunca precisa vê-las (você só precisa tê-lo disponível para adicionar novos kernels, por exemplo).

Casey
fonte