Acabou sendo mais fácil e mais difícil do que o previsto.
Primeiro, o Gentoo (assim como muitas outras distros, até onde eu sei), corrigiu o Grub para poder ler o GPT, assim, todo o incômodo com o MBR híbrido não é necessário, ele funciona com o GPT puro.
É mais fácil, porque o padrão setup (hd0,0)
funciona, como em 'faz um sistema inicializável'. No entanto, o sistema não é robusto o suficiente para os meus padrões - porque setup
não pode incorporar o stage1.5 em nenhum lugar, ele recorre ao patch2 e inclui sua localização no disco em MBR. Então, se alguma coisa mudar o cenário2, alterando os blocos onde estava anteriormente, obtenho um sistema não inicializável. O que é pior, eu posso não notar primeiro - um upgrade move o stage2 para um local diferente, mas o antigo permanece intacto. O sistema ainda inicializa, não noto nada. Mas desde que o código usado durante a inicialização é agora o espaço livre do POV do sistema de arquivos, algo mais tarde substitui-lo aleatoriamente e boom.
Então, recorri aos passos descritos no final da minha pergunta, incorporando manualmente o estágio 1.5.
Primeiro, faça uma cópia do arquivo stage1.5 apropriado e ative um editor hexadecimal nessa cópia. Caso você não tenha um à mão, obtive sucesso com vim e xxd - edite o arquivo, digite :!xxd<enter>
edite o arquivo como hexadecimal, digite :!xxd -r<enter>
e salve. O arquivo recebe um avanço de linha extra no final, mas é inofensivo. Observe que, neste caso, a parte ASCII à direita é completamente ignorada, apenas os dígitos hexadecimais são usados.
Você precisa editar 3 coisas neste arquivo:
- Coloque o número de bloco do bloco segundo em que o estágio1.5 será incorporado, no deslocamento
0xf8
. Note que é little-endian e relativo ao início do disco. Como a partição de inicialização do BIOS inicia no setor 1024, isso é 1025, ou0x0401
ou (em little-endian) bytes0104
. - Insira o número de setores de 512 bytes do estágio1.5, menos um, no deslocamento
0x1fc
. Como meu stage1.5 é 9908 bytes (9909 com a nova linha extra), são 20 setores (como 19 setores é19*512=9728
e 20 setores é 10240 bytes, então eu preciso colocar 19, ou hex13
lá. / li> - Altere
ff
no deslocamento 219 para00
. Não toque noff
nas proximidades.
Aqui está uma comparação dos arquivos originais e modificados do hexdump:
-000001f0 00 00 00 00 00 00 00 00 02 00 00 00 00 00 20 02 |.............. .|
+000001f0 00 00 00 00 00 00 00 00 01 04 00 00 13 00 20 02 |.............. .|
00000200 ea 70 22 00 00 00 03 02 ff ff ff 00 00 00 00 00 |.p".............|
-00000210 02 00 30 2e 39 37 00 ff ff ff ff 2f 62 6f 6f 74 |..0.97...../boot|
+00000210 02 00 30 2e 39 37 00 ff ff 00 ff 2f 62 6f 6f 74 |..0.97...../boot|
A maneira como isso funciona é que o primeiro setor do estágio1.5 lê os números de perto do fim e lê muitos setores, começando de um especificado a partir do início do disco. Isso carrega os demais setores do stage1.5 para a memória e depois os executa. A terceira parte é na verdade uma localização do stage2 no disco, onde o grub precisa encontrar a partição correta. O código relevante, caso esteja interessado, está em stage2/disk_io.c
nas fontes do grub, apenas tenha em mente que você usa a parte em #ifdef STAGE1_5
, e o primeiro setor, que carrega o restante, está em stage2/start.S
. Provavelmente é possível ter o stage1.5 em várias partes não contínuas, mas eu não tentei.
Depois de escrever o estágio modificado1.5, copie-o para a partição de destino (o quarto no meu exemplo), usando cat
ou dd
, de acordo com sua preferência.
Finalmente, no shell do grub, execute
install /boot/grub/stage1 (hd0) (hd0)1024+20
com (hd0) sendo o nome do grub do dispositivo que você está usando, 1024
é o início do stage1.5 incorporado (aliás, início da partição de inicialização do BIOS) e 20
é o tamanho do stage1. 5 em blocos. Isso conclui o procedimento.