Kexec to GRUB (or to Syslinux, or Windows)

bootgrubgrub2kexec

I have an application where I need to boot to Linux, execute automated scripts and then automatically boot to Windows. Can I use Kexec to run grub?

Another use case would be to boot a Linux kernel to update the processor microcode, and then kexec to GRUB or Syslinux to boot Windows — because the microcode won't survive a full reboot.

I've heard of grub4dos (link (unavailable), archived version), but it seems to be discontinued, so is there a way to do it with GRUB2?

I would basically need a loadable image of GRUB for kexec. I tried to load the images found in this explanation, but they don't seem to work. Thanks for any hints.


Note:
Found this post from back in 2014, which said that this was not yet implemented in kexec.

Best Answer

It seems to be possible to kexec Windows, but it seems to be experimental at best (and not well tested).

GRUB

It's not possible to kexec the grub core.img by itself (as it doesn't seem to have a compatible binary format), also see this bug report on launchpad. The error mentioned is still reproducible:

kexec -l /boot/grub2/i386-pc/core.img

According to kexec --help, the following types are supported at the moment:

elf-x86_64
multiboot-x86
multiboot2-x86
elf-x86
bzImage64
bzImage
beoboot-x86
nbi-x86

If you want to load a different loader, it would need to be in one of these formats or the compatibility would have to be added. I'm not sure what format GRUB is using - a simple file command only produces this:

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

Creating a bootable GRUB Image

Currently there seem to be these possibilities:

lnxboot

lnxboot.img would be a Linux kernel x86 boot executeable bzImage. It seems to be intended to be loaded as a kernel:

You can then load grub2.bin from syslinux/isolinux/pxelinux/lilo or any other boot loader that supports linux kernel.

Kexec does load it, but crashes when executing:

kexec -l /usr/lib/grub/i386-pc/lnxboot.img --initrd=/boot/grub2/i386-pc/core.img --debug

There also seems to be an issue occuring while loading (first few lines of debug output):

Try gzip decompression.
Try LZMA decompression.
lzma_decompress_file: read on /usr/lib/grub/i386-pc/lnxboot.img of 65536 bytes failed
[...]

Grub4Dos

A quick look at Grub4Dos:

# file grub.exe
grub.exe: Linux kernel x86 boot executable bzImage, version \353kHdrS\003\002, RO-rootFS, Normal VGA

This should mean that it is compatible. It wasn't an option for me as it's legacy software.

However, I managed to load grub4dos by downloading 0.4.4 from sourceforge and then running:

kexec -l grub.exe
kexec -e

Unconfigured, it falls back to the grub shell after some time. If you want to use gru4dos, you should only need to tweak the cmdline to fit your needs. This thread should still apply.

Windows

Kexec'ing Windows doesn't seem to be a one-liner, but it has been done before.

Most of the work in this direction seems to be associated with the LinuxBoot project. Github

I found these slides as well as this github repo. This seems to be the project mentioned in the article that was making it work.

It seems to be possible, but a lot of work (and no "production-ready" solution available - At least I haven't found it yet). Unfortunately there doesn't seem to be a lot of documentation for LinuxBoot, so you may have to ask the developers. There may already be a more straightforward way to do this.

Related Question