GRUB

GRUB

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, kexecGRUB 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 kexeco Windows, mas parece, na melhor das hipóteses, experimental (e não bem testado).

GRUB

Não é possível fazer kexeco grub core.imgsozinho (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 filecomando simples produz apenas isto:

/boot/grub2/i386-pc/core.img: data

Criando uma imagem GRUB inicializável

Atualmente parece haver estas possibilidades:

lnxboot

lnxboot.imgseria 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 grub4dosbaixando 0.4.4desourceforgee 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 cmdlinepara 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:

  1. 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.

  2. 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.

  3. 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

kexecpode funcionar se você combinar essas duas imagens do grub: lnxboot.imge 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.imageparece 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-mkimagegerar alguns formatos diferentes e ver o que funciona? Na página de manual, -O, --format=FORMATele suporta vários outros formatos. Talvez tente o x86_64-xenformato.

informação relacionada