2010-12-19

How to boot GRUB from SysLinux

This blog post explains how to boot GRUB from SysLinux. Only GRUB1 is covered, the solution explained doesn't support GRUB2.

Older versions of SysLinux (such as 3.83) don't support booting GRUB, i.e. they cannot load and boot the stage2 file of GRUB. The newest version of SysLinux contains chain.c32, which can boot many operating systems and bootloaders, including GRUB. The solution explained here doesn't use this feature, so it works with old versions of SysLinux as well.

The fundamental idea is to convert the GRUB stage2 file to a format which SysLinux can boot directly. This format is bzimage, the big variant of the Linux kernel image. grub.exe, part of GRUB4DOS is already in this format, so adding the following lines to syslinux.cfg works:

label grub4dos
menu label GRUB4DOS
kernel grub.exe

However, one might wish to use the original GRUB instead, because GRUB4DOS has some features missing, e.g. it doesn't support GPT (GUID Partition Table) and UUID on reisrefs partitions. Converting the original GRUB stage2 file to bzimage format is easy: just append it to the first 20480 bytes of grub.exe. SysLinux can boot this hybrid, but then GRUB wouldn't be able to find its configfile (menu.lst). To fix that, the full pathname of the configuration file has to be embedded to the boot image. The Perl script grub2bzimage.pl automates this.

grub2bzimage is a Perl script which converts the GRUB bootloader code (stage2) to bzimage format, which can be booted directly by SysLinux and other bootloaders. grub2bzimage.pl doesn't support GRUB2.

Example use to create grubzimg:

$ perl ./grub2bzimage.pl stage2 grubzimg '(hd0,0)/boot/grub/menu.lst'
Write this into syslinux.cfg:
label grub
menu label GRUB
kernel grubzimg

Please note that it's not possible to specify the name of the configfile (menu.lst) in syslinux.cfg (using append). The configfile has to be specified when grubzimg is created.

grub2bzimage.pl has been tested with SysLinux 3.83. Please note that newer versions of SysLinux contain chain.c32 which supports loading GRUB stage2 files directly.

3 comments:

zsbana said...

Could you explain your motivation of why you want this? Do you want to load grub from network? I don't see the utility, as you seem to need the menu.lst on a local drive (hard disk or floppy) in any case.

Also, would it also be possible to load only the a modified stage1 of grub from syslinux, and let it load the rest of grub from a local disk? (That would work only from a hard disk or floppy disk, not a cdrom, but if you have a cdrom then you can boot grub from it directly instead.) At least I seem to remember I could load a LILO installed to sectors after the MBR by modifying its boot sector to load as a DOS com file.

pts said...

@zsbana

> Could you explain your motivation of why you want this?

I needed it for dual-booting on a system which booted SysLinux by default, and I was not allowed to reorganize this. I was allowed to change syslinux.cfg though. Once I could load my GRUB from SysLinux, I was in total control of my branch of the dual-boot.

> would it also be possible to load only a modified stage1 of grub from syslinux

Yes, most probably (SysLinux can chainload boot sectors, COM files etc. with chain.c32). But simple similar attempts didn't work on that system with the very old SysLinux, so I just settled with this way to boot GRUB.

zsbana said...

I used to have a configuration on my home computer where I booted Windows 95 OSR2 using a specialized boot floppy, and booted the other systems (DOS and a Suse Linux) from the boot manager on the hard disk. I found out much later that this is probably not a unique crazy idea I had, because the OpenBSD FAQ mentions this technique ("http://openbsd.org/faq/faq4.html#Multibooting"). Also just recently I used a USB pendrive to boot a Debian installation on a notebook, because I had problems with installing GRUB on the hdd for some reason and didn't want to bother much with what was just a temporary situation.