Linux multi-boot part 2 (booting)

In yesterday’s post, I discussed ways of having multiple linux installs on that same computer, using my laptop as an example.  Today, I continue with that, but mostly concentrate on the details of booting.

If you have multiple versions of linux installed, then you presumably want to be able to boot any of them.  Fortunately, linux usually installs a boot manager, typically grub2, which provides a menu that allow selecting which system to boot.

The problem

There are a couple of problems with this.  Firstly, the most recent linux that is installed usually takes over the booting.  And that might not be what you want.  And, secondly, if there is a kernel update on one of the installed linux versions that is not controlling the boot, that might cause problems on the next boot unless the boot menu that you use is updated.

I deal with this in two ways.  Firstly, I make sure that each linux system can boot the others.  And, secondly, I add my own entries to the boot menu for booting the other systems in a way that will still work if they update their kernels.

Adding boot entries

To add boot entries, I use the file “40_custom” in /etc/grub.d”.  As installed, that’s a small file (around 4 lines, mostly comments).  I add entries after those lines.

Legacy booting

I’ll start with what I do in my laptop, that uses legacy booting.  Here are the lines that I have added:

### Entry to boot grub from "/dev/sda5"
menuentry "Alternate grub/linux on /dev/sda5"  {
        set root=(hd0,5)
        chainloader +1
}
menuentry "configfile for grub/linux on /dev/sda5" {
       configfile (hd0,5)/grub2/grub.cfg
}
### Entry to boot grub from "/dev/sda8"
menuentry "Alternate grub/linux on /dev/sda8"  {
        set root=(hd0,8)
        chainloader +1
}
menuentry "configfile for grub/linux on /dev/sda8" {
       configfile (hd0,8)/boot/grub2/grub.cfg
}

That adds several lines to the boot menu.

The lines quoted are from “40_custom” in the linux that boots from “/dev/sda1” as “/boot” (opensuse 13.2).  There are two ways of booting each of the other linux version.  The first uses chain loading.  With that, grub2 reads the boot sector into memory and restarts booting with that boot sector.  The other method uses “configfile”.  This allows running the “grub.cfg” from the wanted system.

Either of those methods should work.  I use both, because I sometimes want to test the different ways of doing it.

You will notice that for booting “sda5” with configfile, I use “/grub2/grub.cfg”, while for booting “sda8” I use “/boot/grub2/grub.cfg”.  The difference is that I do not have a separate “/boot” partition with the linux on “/dev/sda8”.

If there is a kernel update on Tumbleweed (installed on “/dev/sda8”), then updating that kernel will have automatically updated the file “/boot/grub2/grub.cfg” for that version of linux.  By either chainloading or using that “grub.cfg” with “configfile”, I use an updated boot command for that linux.  I don’t have to update the boot menu on opensuse 13.2 for that to work.

This does give me a second menu, but I usually just hit Enter on that menu.

UEFI booting

Chain loading means something rather different for UEFI booting.  So I don’t use that.  I only use “configfile”.

Here’s a typical boot entry from 40_custom

### Entry to boot Leap on sdb3
menuentry "configfile for linux on /dev/sdb3 (Leap)"  {
        set bootdir='hd1,gpt3'
        search --fs-uuid --set=bootdir 6ace6c07-8515-4cad-8012-d1d9600bc61d
        configfile (${bootdir})/boot/grub2/grub.cfg
}

Why the difference?  That’s mainly because I have two hard drives on that computer, and the disk designation (hd0 or hd1) might not be right.  So I locate the partition via a search for it’s UUID.  The partition identification is then assigned to “$bootdir” and I use that load the “grub.cfg” configuration file.

This does mean that if I reinstall that linux, the UUID of the partition might change and I will need to update the 40_custom that refers to that linux system.

Which linux is in control

The other issue that I mentioned, is that of which linux system controls the booting.  This also varies depending on whether the system uses legacy BIOS booting or UEFI booting.

Legacy booting

With legacy booting, which one is in control depends on the active flag in the partition.  Normally, the active flag can only go in a primary partition.  However, if the boot code in the MBR comes from the “syslinux” project, it can actually boot logical partitions with an active flag.  I am using syslinux boot code.

During install of opensuse, I normally tell the installer to boot from “/boot” or from “/” if there is no separate boot.  And I tell it to not install generic boot code and to not set the active flag.  That way, it leaves booting the way that it was.  I can change the active flag later with “fdisk”.

UEFI booting

With UEFI booting, the boot code is in the directory “/boot/efi/EFI/opensuse”.  And that directory is shared by all systems.  So the last one wins.

After experimenting with other ways of solving the problem, my current method is to have a subdirectory for each installed system.  On install, I copy the boot files to the subdirectory.  And then I can control which is in charge of booting, by copying that subdirectory back to the main directory (i.e. back to “/boot/efi/EFI/opensuse”).

If a system updates its booting software, it reinstalls.  I’ll usually notice that because it changes which system is in charge of booting.  So I again copy the files back to the subdirectory, and copy the files from the preferred subdirectory back to the main directory.  Tumbleweed often updates the boot software.

Final remarks

That about sums up how I handle multiple unix systems.

If I do not have Windows installed, then I turn off the option to “probe foreign operating systems”.  I don’t need that because I am providing my own boot entries with “40_custom”.  On systems with Windows, I do need to probing to generate Windows boot menu entries.

And, please note:  adding lines to “40_custom” doesn’t do anything until after you run the command

# grub2-mkconfig -o /boot/grub2/grub.cfg

to update the menu.

Advertisements

Tags: ,

About Neil Rickert

Retired mathematician and computer scientist who dabbles in cognitive science.

Trackbacks / Pingbacks

  1. Links 27/1/2016: Tails 2.0, GPUOpen | Techrights - 2016/01/27

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: