
Tenho um aplicativo onde preciso inicializar no Linux, executar scripts automatizados e depois inicializar automaticamente no Windows. Posso usar o Kexec para executar o grub?
Outro caso de uso seria inicializar um kernel Linux para atualizar o microcódigo do processador e, em seguida, kexec
GRUB ou Syslinux para inicializar o Windows - porque o microcódigo não sobreviverá a uma reinicialização completa.
Eu já ouvi falar grub4dos
(link (indisponível),versão arquivada), mas parece ter sido descontinuado, então existe uma maneira de fazer isso com o GRUB2?
Eu basicamente precisaria de uma imagem carregável do GRUB para kexec
. Tentei carregar as imagens encontradas nesteexplicação, mas eles não parecem funcionar. Obrigado por qualquer dica.
Nota: Encontradoesta postagemde 2014, que dizia que isso ainda não foi implementado no kexec.
Responder1
Parece ser possível para kexec
o Windows, mas parece, na melhor das hipóteses, experimental (e não bem testado).
GRUB
Não é possível fazer kexec
o grub core.img
sozinho (pois não parece ter um formato binário compatível), veja tambémeste relatório de bug no launchpad. O erro mencionado ainda é reproduzível:
kexec -l /boot/grub2/i386-pc/core.img
De acordo com kexec --help
, os seguintes tipos são suportados no momento:
elf-x86_64
multiboot-x86
multiboot2-x86
elf-x86
bzImage64
bzImage
beoboot-x86
nbi-x86
Se você quiser carregar um carregador diferente, ele precisará estar em um desses formatos ou a compatibilidade deverá ser adicionada. Não tenho certeza de qual formato o GRUB está usando - um file
comando simples produz apenas isto:
/boot/grub2/i386-pc/core.img: data
Criando uma imagem GRUB inicializável
Atualmente parece haver estas possibilidades:
grub2-mkimage
- uma parte de
core.img
(kernel.img
) - juntando
lnxboot.img
ecore.img
juntando. Veja a resposta de @Ardwena. lnxboot.img
como kernel ecore.img
comoinitrd
. Dica encontrada emArco Wikieum tópico antigo na lista de discussão grub devel.
lnxboot
lnxboot.img
seria um Linux kernel x86 boot executeable bzImage
. Parece que foi planejado para ser carregado como um kernel:
Você pode então carregar grub2.bin de syslinux/isolinux/pxelinux/lilo ou qualquer outro carregador de boot que suporte o kernel Linux.
Kexec carrega, mas trava ao executar:
kexec -l /usr/lib/grub/i386-pc/lnxboot.img --initrd=/boot/grub2/i386-pc/core.img --debug
Também parece haver um problema durante o carregamento (primeiras linhas da saída de depuração):
Try gzip decompression.
Try LZMA decompression.
lzma_decompress_file: read on /usr/lib/grub/i386-pc/lnxboot.img of 65536 bytes failed
[...]
Grub4Dos
Uma rápida olhada no Grub4Dos:
# file grub.exe
grub.exe: Linux kernel x86 boot executable bzImage, version \353kHdrS\003\002, RO-rootFS, Normal VGA
Isso deve significar que é compatível. Não era uma opção para mim, pois é um software legado.
Porém, consegui carregar grub4dos
baixando 0.4.4
desourceforgee então executando:
kexec -l grub.exe
kexec -e
Não configurado, ele retorna ao shell do grub depois de algum tempo. Se você quiser usar o gru4dos
, você só precisará ajustá-lo cmdline
para atender às suas necessidades.Este tópicoainda deve ser aplicada.
janelas
Kexec
'ing Windows não parece ser uma linha única, masjá foi feito antes.
A maior parte do trabalho nesta direção parece estar associada aoInicialização Linuxprojeto.GitHub
Eu encontrei estesdiapositivosassim como issorepositório do github. Este parece ser o projeto mencionado no artigo que o fez funcionar.
Parece possível, mas dá muito trabalho (e nenhuma solução "pronta para produção" disponível - pelo menos ainda não a encontrei). Infelizmente não parece haver muita documentação para o LinuxBoot, então você pode ter que perguntar aos desenvolvedores. Talvez já exista uma maneira mais direta de fazer isso.
Responder2
A razão pela qual fazer kexec no Windows é tão difícil e complicado é porque o mecanismo de design interno do kexec tem uma imperfeição que pressupõe que todos os carregadores de inicialização do sistema operacional carregam a imagem do kernel do sistema operacional de maneira semelhante, o que claramente não é o caso. Por exemplo, alguma imagem do kernel do sistema operacional deve ser carregada a partir de algum deslocamento de endereço de memória especial, alguns sistemas operacionais podem exigir o carregamento de arquivos adicionais (que contêm informações do driver) junto com a imagem do kernel do sistema operacional, etc. imagem do kernel, ou carregará sua imagem do kernel em uma versão futura, a maneira atual de executar kexec em outro sistema operacional/kernel não funcionará muito bem no longo prazo.
A maneira mais universal/compatível (como proponho) de fazer kexec em outro sistema operacional écarregue o código de inicialização do setor de inicialização em modo real, saia do modo protegido e, em seguida, vá diretamente para o ponto de entrada do código de inicialização em modo real. Esta é a maneira mais universal porque o código de inicialização do setor de inicialização em modo real de qualquer sistema operacional sempre pode ser carregado começando em qualquer endereço de memória, é assim que o BIOS (diferentes fabricantes de computadores fazem BIOS diferentes) inicializa em um sistema operacional (a menos que um sistema operacional faça isso). Se você não quiser que outro BIOS o instale ou inicialize, por exemplo, Apple, eles podem impor restrições proprietárias sobre como carregar códigos de inicialização do setor de inicialização). Dessa forma, sempre podemos inicializar qualquer sistema operacional, independentemente de como seu código de inicialização carrega a imagem do kernel do sistema operacional, simplesmente porque estamos executando diretamente seu próprio código de inicialização do setor de inicialização. Além disso, este modo não introduz nenhuma lentidão porque o código de inicialização do setor de inicialização é pequeno e, portanto, rápido de carregar, e a diferença no carregamento de um arquivo grande de imagem do kernel no modo real versus no modo protegido não é muito grande.
No entanto, conseguir isso é muito desafiador porque:
Para todos os sistemas operacionais modernos, uma vez que eles entram no modo protegido a partir do modo real, a memória do modo real é sobrescrita por algumas tabelas de descritores ou entradas de tabelas de páginas. Portanto, não há backup. No entanto, os códigos de inicialização em modo real usam interrupções do BIOS para acessar IO de hardware, portanto, sem restaurar o mapa de memória em modo real original, eles não serão capazes de carregar o arquivo de imagem do kernel do disco rígido. Este problema é complicado, mas solucionável. Podemos instalar algum gerenciador de inicialização Linux especial que tira um instantâneo da memória antes de entrar no modo protegido e isso só precisa ser feito uma vez por todas em uma máquina.
Nem todos os processadores suportam voltar ao modo real a partir do modo protegido. Os processadores modernos são projetados para inicializar em um sistema operacional (entrando no modo protegido a partir do modo real), em vez de cancelar a inicialização de um sistema operacional (retornando ao modo real a partir do modo protegido), por razões de custo de produção e eficiência. Assim, o comportamento de retornar ao modo real a partir do modo protegido não foi bem testado e, portanto, muito indefinido. Como esse comportamento varia em cada modelo, não há controle e portanto não há garantia de em quais marcas/modelos de processadores ele funcionará corretamente.
Apenas os processadores Intel X86 possuem modo real e modo protegido (porque passaram por uma tecnologia legada em estágio inicial). Assim, o mecanismo de reinicialização a partir do setor de inicialização será diferente para diferentes arquiteturas de processador, não envolvendo necessariamente o retorno ao modo real a partir do modo protegido, mas pode envolver algumas outras opções nos estados operacionais do processador.
No entanto, deve funcionar em princípio se tudo for bem cuidado. No futuro, o Linux deverá ter a capacidade de executar kexec em qualquer partição inicializável montada (mas não necessariamente marcada como inicializável porque cada disco rígido pode ter apenas uma partição marcada como inicializável, ou o BIOS irá reportar um erro e se recusar a inicializar) diretamente de qualquer disco rígido, sem uma reinicialização completa do hardware, o que é muito mais lento. Isso lançou mais luz e esperança para o Linux ^_^
Responder3
Você precisa ter o grub instalado e o sistema Linux como inicialização padrão.
No sistema Linux, crie uma entrada crontab como esta:
@reboot /do/some/stuff
Onde /do/some/stuff é um script para executar qualquer tarefa que você precise fazer. No final do script adicione o seguinte:
#!/bin/bash
#
# Do something here
sudo grub2-once "Windows"
sudo reboot
Ele deve então reiniciar no Windows, desde que o item de menu grub para Windows seja "Windows".
Na próxima reinicialização, ele voltará ao Linux e fará a mesma coisa.
Responder4
kexec
pode funcionar se você combinar essas duas imagens do grub: lnxboot.img
e core.img
, como...
cat lnxboot.img core.img > your-kexec-able.img
Vale a pena tentar isso.
EDITAR:
Agora que olhei dentro das imagens, lnxboot.image
parece mais um "ELF" do que lnxboot.img
, então tente esse também.
EDITAR:
Aparentemente, as imagens /boot/grub2/i386-pc/xxx.img não são do agrado de kexec
. Então por que não tentar grub-mkimage
gerar alguns formatos diferentes e ver o que funciona? Na página de manual, -O, --format=FORMAT
ele suporta vários outros formatos. Talvez tente o x86_64-xen
formato.