Pelo que entendi, o bootloader GRUB em um sistema BIOS (e a maioria dos outros bootloaders) são compostos de 3 partes. A primeira parte (estágio 1) é armazenada nos primeiros 448
bytes, que é responsável por passar o controle para o chamado estágio 1.5, localizado um pouco mais adiante na memória. Este estágio finalmente carrega o estágio 2 da pasta /boot e transfere o controle para ele.
Como o estágio 1 sabe em qual estágio de disco 1.5 reside? Uma vez que o código no estágio 1 começa a ser executado, não há como ele saber de qual disco foi carregado (a menos que essa informação seja de alguma forma passada para o estágio 1 ou o próprio BIOS também carregue o estágio 1.5 na memória?)
Do estágio 1.5 ao estágio 2, novamente, como o estágio 1.5 sabe em qual disco (e em qual partição) o diretório /boot reside?
Os nomes "stage1", "stage1.5" e "stage2" pertencem ao GRUB Legacy, ou seja, versões 0.xx do GRUB. Quando o estágio 1 é gravado no MBR (ou PBR), o instalador também gravará nele o número do bloco de disco real onde o início do próximo estágio estará localizado. O primeiro bloco do próximo estágio conterá mais código de programa e uma lista de bloqueios descrevendo onde o restante do estágio está localizado. As entradas da lista de bloqueio são do formato "carregar X blocos começando do bloco de disco #Y". Se o próximo estágio foi gravado no disco como um arquivo contíguo (não fragmentado), geralmente era necessária apenas uma entrada da lista de bloqueio.
O stage1.5 era na verdade opcional: era perfeitamente possível não instalar o stage1.5 e apenas fazer com que o stage1 carregasse o stage2 diretamente. O estágio 1.5 conteria código suficiente para poder entender um único tipo de sistema de arquivos; stage2 conteria todos os drivers de sistema de arquivos suportados, o que o tornaria muito maior. Dessa forma, stage1.5 pode ser embutido no espaço normalmente não utilizado entre o MBR e o início da primeira partição.
(Os discos particionados por MBR modernos agora iniciam a primeira partição exatamente a 1 MiB do início do primeiro disco, ou seja, no bloco #2048, para permitir um alinhamento de dados ideal para grandes sistemas de armazenamento. Isso deixa muito mais espaço não utilizado entre o MBR e o início da primeira partição do que a antiga convenção para iniciar a primeira partição em C/H/S 0/1/1.)
Tanto o stage1.5 quanto o stage2 tinham um espaço pré-alocado dentro deles, para o instalador gravar um identificador de disco GRUB e um nome de caminho. No caso do stage1.5, isso identificaria a partição e o nome do arquivo em que o stage2 real estava localizado; no caso do stage2, ele identificaria a localização do arquivo de configuração do GRUB.
GNU GRUB (ou seja, GRUB versões 1.xx e acima) em sua forma compatível com BIOS pula totalmente o estágio 1.5 e usa nomes diferentes:
stage1
é agoraboot.img
stage2
é agoracore.img
Ainda são 448 bytes que são incorporados ao
boot.img
MBR, mascore.img
são construídos dinamicamente no momento da instalação do GRUBkernel.img
e um conjunto de módulos GRUB.A convenção padrão de fato do BIOS era que qualquer disco selecionado do BIOS como o disco para inicializar seria atribuído ao ID 0x80 para funções de acesso ao disco do BIOS, e esse ID seria mapeado diretamente para o GRUB
(hd0)
. (O antigo MS-DOS também sempre mapeava o ID de disco do BIOS 0x80 para a unidadeC:
.)Felizmente, o BIOS geralmente era bastante determinista em como enumerava os diferentes controladores de disco. Portanto, desde que a configuração de hardware e as configurações do BIOS fossem mantidas as mesmas, a ordem de detecção do disco permaneceria a mesma de uma inicialização para a próxima.
Mas sim, essa definitivamente era uma estratégia frágil; infelizmente, não havia uma maneira padrão onipresente de passar as informações de detecção de disco do BIOS das rotinas do BIOS de 16 bits para um sistema operacional que usa programação em modo protegido de 32 bits (ou mesmo 64 bits). Como resultado, todos os sistemas operacionais de 32 bits ou melhores detectarão novamente seus discos do zero após alternar do carregador de inicialização baseado em BIOS para o modo completo de 32 bits ou 64 bits.
Sim, o BIOS Enhanced Disk Drive Services (EDD para abreviar) inclui uma extensão do BIOS que pode ser usada para relatar os detalhes essenciais da detecção de disco do BIOS para um sistema operacional em modo protegido... parte era opcional , então sua disponibilidade está longe de ser garantida.
Em sistemas baseados em BIOS com mais de um controlador de disco, isso era basicamente uma dor de cabeça padrão.
A estratégia vencedora geralmente seria testar as configurações de inicialização do BIOS completamente ao encontrar um modelo de hardware específico pela primeira vez (possivelmente fazendo várias instalações de teste do sistema operacional) e, uma vez encontrada uma boa configuração, anote-a e não toque no BIOS configurações de inicialização depois disso.
O GNU GRUB moderno inclui o
search
comando que pode ser usado para selecionar partições de disco por seu rótulo, UUID e/ou pela presença de um arquivo específico. Em umgrub-mkconfig
arquivo de configuração GRUB 2.xx gerado moderno, os identificadores fixos geralmente devem ser a opção de último recurso, a serem usados somente se ossearch
comandos anteriores falharem.A tabela de partição GPT inclui UUIDs exclusivos para cada disco e partição como padrão, e as variáveis UEFI NVRAM realmente especificam a localização do carregador de inicialização usando o UUID da partição do ESP + o nome do caminho do carregador de inicialização dentro da partição ESP. Isso permite uma configuração muito mais robusta. Há também uma interface padrão para o sistema operacional em execução para ler as informações de inicialização do firmware UEFI e modificar as configurações de inicialização, se necessário.
Se você olhar as fontes do GRUB, disponíveis aqui , você descobrirá que stage1 está realmente definido em
grub/grub-core/boot/i386/pc/boot.S
.Ele pode executar uma inicialização por disquete se configurado. Ele inicializa a partir de um disco rígido configurado e precisa saber de qual C/H/S deve carregar o stage1.5. A única função automática que possui é determinar de qual unidade o setor de inicialização foi carregado, se não estiver configurado de outra forma. Um BIOS funcional carregará esse valor no DL antes de passar o controle para o stage1. Alguns não e o grub volta para o primeiro disco rígido.
stage1.5 já é capaz de entender partições e sistemas de arquivos, então ele não depende mais de valores C/H/S. A unidade que carrega ainda é a mesma acima.