(Tutorial) Como iniciar sua distro Linux direto pelo kernel e agilizar seu boot! (EFISTUB)

Depois de uma discussão em um tópico promovida por mim, o @Talls, @Natanael.755, @EsTeVaO e eu descobrimos a existência do EFISTUB. Terminei a saga da busca de informação e vou descrever aqui como fazer pra iniciar o linux direto pelo kernel, sem passar pelo grub, utilizando do EFISTUB.

vou deixar passo a passo aqui de uma forma um pouco mais amigável do que eu encontrei no artigo do qstack e na ArchWiki .


1. Monte a partição efi e copie os arquivos do kernel para lá

Você precisa copiar os arquivos vmlinuz e os initrd.img para a pasta /boot/efi/EFI/ubuntu/ (no caso de estar usando o Ubuntu, obviamente) para inicializar direto por eles.

(Os diretórios do /boot/efi não possuem permissão de acesso nem com o sudo, no meu caso, então pode ser necessário estar logado como root no terminal, com o comando sudo su.)

E o comando é

cp -uv /boot/vmlinuz-* /boot/initrd.img-* /boot/efi/EFI/ubuntu/


2. Altere o nome do arquivo do kernel

Existe uma suposta limitação de caracteres para o caminho até o kernel* (vmlinuz), então precisamos diminuir o nome dele.

E o comando é

for f in /boot/efi/EFI/ubuntu/vmlinuz-*-generic; do mv -uv -- "$f" "${f//-generic/}.efi"; done

*note que todos os comandos até aqui, e também os próximos, independem da versão do kernel utilizada, porém, para o kernel de linha prinicipal dpkg, é necessária uma abordagem diferente, pois ainda permanece com nome muito grande depois do comando acima.


3. Adicione uma nova entrada ao menu de inicialização EFI

Aqui será o momento em que você pode definir a menu entry.

O comando base é o abaixo, substituindo yourKernelVersion com a versão do seu Kernel, o rootDisk com o disco e partição onde se encontra a raíz do sistema (/), e também o fileSystemType com o sistema de arquivos do seu sistema:

kv=yourKernelVersion;efibootmgr -c -p 3 -L $kv -l \EFI\ubuntu\vmlinuz-$kv.efi -u root=/dev/rootDisk initrd=\\EFI\\ubuntu\\initrd.img-$kv-generic ro rootfstype=fileSystemType debug ignore_loglevel libata.force=dump_id crashkernel=384M-:128M

Um exemplo para a minha máquina com kernel 5.8.0-59, sistema na partição 1 do ssd nvme, e em sistema de arquivos em ext4, o comando ficaria dessa forma:

kv=5.8.0-59;efibootmgr -c -p 3 -L $kv -l \EFI\ubuntu\vmlinuz-$kv.efi -u root=/dev/nvme0n1p1 initrd=\\EFI\\ubuntu\\initrd.img-$kv-generic ro rootfstype=ext4 debug ignore_loglevel libata.force=dump_id crashkernel=384M-:128M

(Para um HD comum, o disco é descrito na fórmula sdXx, onde ‘‘X’’ é o próprio disco e ‘‘x’’ a partição. Ex.: sda2).

Dessa forma, essa nova entrada do menu de inicialização se tornará padrão no seu boot.

Segue aí uma pic da saída do comando systemd-analyze depois disso:


(era 25s antes)

Só não é mais rápido do que isso por conta dos snaps que incomodam um pouco o boot.

8 curtidas

Pra descobrir os parâmetros atuais de boot a dica é: cat /proc/cmdline

Pra facilitar o entendimento, o comando efibootmgr tem opções por extenso que facilita pro usuário entender o que é o quê, e alterar conforme seu próprio sistema. Uma batucada em efibootmgr --help já dá as dicas. Por exemplo o comando ficaria:
efibootmgr --create --part 3 --label $kv --loader \EFI\ubuntu\vmlinuz-$kv.efi --unicode root=/dev/rootDisk initrd=\\EFI\\ubuntu\\initrd.img-$kv-generic ro rootfstype=fileSystemType debug ignore_loglevel libata.force=dump_id crashkernel=384M-:128M

Pra visualizar a versão corrente do kernel, o comando uname -r já dá certinho. Se usar as ferramentas do shell, pode setar a variável direto com a saída do comando: kv=$(uname -r)

Pra descobrir a partição atual é só pesquisar quem está montado atualmente no /boot/efi. Já dá o nome do dispositivo: mount | grep /boot/efi

Eu adicionaria também a opção “–disk /dev/sda” porque alguns outros computadores podem ter a partição efi em outro disco, e o comando sem parâmetros vai escrever no sda, podendo não gerar o comportamento esperado.

Também é interessante criar seu próprio diretório na partição efi, pra evitar confusão com o atual bootloader: mkdir /boot/efi/EFI/stub e copiar os arquivos para lá.

Outro ponto interessante é usar aspas nos parâmetros, para evitar a confusão de valores. Juntanto tudo:

efibootmgr --create --disk "/dev/sda" --part 3 --label "$(uname -r)" --loader "\EFI\stub\vmlinuz-$(uname -r).efi" --unicode "initrd=\\EFI\\stub\\initrd.img-$(uname -r)-generic $(cat /proc/cmdline)"


Já usei alguns meses o boot com efistub, ganha uns segundos do grub, mas perde na necessidade de rodar o comando toda vez que altera o kernel. Daí resolvi malandrear e fiz o seguinte:

  • Cria duas entradas pro teu efi. Em uma delas o arquivo será “vmlinuz” e “initrd.img”. Na outra será “vmlinuz.old” e “initrd.img.old”.
  • Copia a versão atual e funcionando do teu kernel pra efi: cp "/boot/vmlinuz-$(uname -r)" "/boot/efi/EFI/stub/vmlinuz" e faz o mesmo pro initrd.
  • Na próxima atualização do kernel, move o kernel stub pro antigo (/boot/efi/EFI/stub/vmlinuz → vmlinuz.old) e copia o recém instalado pro novo (/boot/vmlinuz-receminstalado → /boot/efi/EFI/stub/vmlinuz)
  • Desse modo na próxima inicialização já vau subir a nova versão. Caso tenha algum problema, inicie a entrada do vmlinuz.old.
  • Caso opte por manter o grub, não precisa da entrada pro antigo, pois o reserva será o grub… Eu particularmente gosto do grub porque ele é bem potente pra resolver algumas picuinhas, como por exemplo editar os parametros do kernel sem precisar refazer a entrada UEFI.
4 curtidas

Muito boas as dicas, essa da alteração do kernel é excelente, vou aplicar aqui o quanto antes. De repente, é possível até automatizar esse processo de cópia do vmlinuz e initrd.img com um script da vida. Valeu!

1 curtida