UEFI Grub Dual/Multiboot with/without Windows

Write tutorials for Linux Mint here
More tutorials on https://github.com/orgs/linuxmint/discu ... /tutorials and (archive) on https://community.linuxmint.com/tutorial
Forum rules
Don't add support questions to tutorials; start your own topic in the appropriate sub-forum instead. Before you post read forum rules
Post Reply
bodge99

UEFI Grub Dual/Multiboot with/without Windows

Post by bodge99 »

I was asked to write this up for a neighbour.. so I thought I'd post it here. I hope that this helps someone..

UEFI Dual or Multiboot Linux(s) with or without Windows:

OVERVIEW:
This process initally creates a bootable flashdrive. When you have proved that your flashdrive boots your OS's correctly then just replace the contents of your EFI partition with the contents of your flashdrive. Any existing or new Linux installations are totally untouched and remain 'standard'. They are updated or installed normally. See 'Maintenance Notes' below:
When copied over to the EFI partition, the initial (pre)boot is handled from within the EFI partition. Choosing an OS from the Grub menu then passes control to the OS's specific 'grub.cfg'. By having Grub installed onto the EFI partition, there is no problem adding or deleting any OS on the drive that in any way affects any existing OS. The Grub installation here has full **initial** control.
If you don't wish to use a flashdrive and would prefer to use an external USB SSD/HDD etc. then all you need on this drive is an EFI partition (I just use Gparted to create a suitably sized fat32 partition.. Don't forget to set the 'boot' and 'esp' flags.).

The other advantage is that you now have a bootable flashdrive for those times when Windows updates messes with your boot files.

This method installs Grub to the flashdrive.

Boot your machine to Linux. A Live distro is fine.

Format a flashdrive to fat32. With Gparted, set the 'boot' & 'esp' flags. Quit Gparted and mount the drive to /mnt .

All Linux commands are run as root. It's easiest to just copy & paste each command to a root terminal.

Here, this assumes that your flashdrive is seen by your system as 'sda'. If not, adjust as required.

Code: Select all

  mount /dev/sda1 /mnt
If/when required, unmount the flashdrive using:

Code: Select all

  umount /mnt
Install Grub to the flashdrive with:

Code: Select all

  grub-install --target=x86_64-efi --efi-directory=/mnt --boot-directory=/mnt/EFI/BOOT
Now rearrange the installed files to match this tree, copying your Windows 8/8.1/10 boot files if you use it.
(At this stage, I have Mint 20.1 and Windows 10 installed. Note: the 'ubuntu' directory is empty.)

Code: Select all

/mnt
 └── EFI
     ├── BOOT
     │   ├── BOOTX64.EFI
     │   ├── fonts
     │   │   └── unicode.pf2
     │   ├── grub.cfg
     │   ├── grubx64.efi
     │   ├── locale
     │   │   ├── en_AU.mo
     │   │   ├── en_CA.mo
     │   │   ├── en_GB.mo
     │   │   └── en@quot.mo
     │   └── x86_64-efi
     │       ├── acpi.mod
     │       ├── adler32.mod
          { Truncated Listing. }
     │       ├── zfs.mod
     │       └── zstd.mod
     ├── Microsoft
     │   ├── Boot
     │   │   ├── BCD
     │   │   ├── BCD.LOG
          { Truncated Listing. }
     │   └── Recovery
     │       ├── BCD
     │       ├── BCD.LOG
     │       ├── BCD.LOG1
     │       └── BCD.LOG2
     └── ubuntu
EDIT: I don't use secure boot or need the fallback executable etc. so delete 'fbx64.efi', 'mmx64.efi', 'shimx64.efi' and 'BOOTX64.CSV'.

From a terminal, as Root:

Now overwrite BOOTX64.efi with a new version that has the required root and prefix environment variables set. Also embed some Grub modules.

Set a variable to contain a list of required modules:

Code: Select all

 MODULES="configfile ext2 fat part_gpt part_msdos normal linux ls boot echo reboot search search_fs_file search_fs_uuid search_label help font efi_gop efi_uga gfxterm"
Create the new 'BOOTX64.efi' with:

Code: Select all

 grub-mkimage -O x86_64-efi -p "(hd0,1)/EFI/BOOT" -o /mnt/EFI/BOOT/BOOTX64.EFI $MODULES
Now replace '/mnt/EFI/BOOT/grub.cfg' with the following 'grub.cfg':
Use your own UUID's as indicated by the 'blkid' tool. You can create a text file containing these UUIDs using:

Code: Select all

  blkid > blkid.txt
Sample 'grub.cfg': The entries here call the relevant OS's own 'grub.cfg'. I have Mint, Devuan and Windows 10 here.
(Here, Devuan is to be installed next, onto a pre-prepared partition.)

Code: Select all

menuentry "Mint 20.1 Cinnamon" {
    search --set=root --fs-uuid 214f152c-f910-4dff-bed9-0b023834e50d
    set prefix=($root)/boot/grub
    configfile $prefix/grub.cfg
}

menuentry "Windows 10" {
   search --set=root --fs-uuid 089A-A628
   chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}

menuentry "Devuan Linux" {
    search --set=root --fs-uuid db3325f6-d875-41a5-a268-3d0ec4a12f50
    set prefix=($root)/boot/grub
    configfile $prefix/grub.cfg
}
Adjust Windows to use Grub:

Boot Windows and open a "Command Prompt" (Run as administrator).
Set the boot manager to use Grub:

Code: Select all

  bcdedit /set {bootmgr} path \EFI\BOOT\grubx64.efi
If you ever need to revert then use:

Code: Select all

  bcdedit /deletevalue {bootmgr} path \EFI\BOOT\grubx64.efi
or

Code: Select all

  bcdedit /set {bootmgr} path \EFI\Microsoft\Boot\bootmgfw.efi

Now restart your machine and boot from the flashdrive. Test that each OS can be booted successfully.
When you are happy that everything is working properly, delete the contents of your EFI partition and copy the contents of your flashdrive to your EFI partition.

Use Gparted to identify your EFI partition and flashdrive. On this machine (booted from Linux), the EFI partition is 'sda2' and the flashdrive is now 'sdb1'.
Mount your flashdrive to /mnt and your EFI partition to /mnt1. To be extra safe, make a copy of the existing contents of your EFI partition to /mnt2 (create the /mnt1 & /mnt2 directories as required.).

Code: Select all

  mkdir /mnt1 /mnt2
  mount /dev/sdb1 /mnt
  mount /dev/sda2 /mnt1
  cp -R /mnt1 /mnt2
  rm -R /mnt1/*
  cp -R /mnt/* /mnt1
  sync
  umount /mnt /mnt1
  rm -d /mnt1


I use this method on a number of external USB drives. I've got one with around 30 different installations that I use for demo purposes and another which has a similar number of installation ISO's (isobooted) or as extracted Isos on separate partitions for those ISOs that don't support isobooting.

Maintenance Notes:
General maintenance.
I normally only need to look at the EFI partition for changes after OS Grub updates or after a new installation has been performed. Example: When Mint updates Grub, it places a few new files in '/boot/efi/EFI/ubuntu' and '/boot/efi/EFI/BOOT'.
I merely delete these new files or just delete everything in the /boot/efi/EFI directory and copy the original files back from a local backup. I usually keep a copy of '/boot/efi/EFi/' as '/boot/efi/EFI-BACKUP'

Adding New OS's:

All you need is the UUID of the target partition and the location of the distro's installed 'grub.cfg'.
Most Linux's use '/boot/grub/grub.cfg', some (e.g. OpenSuse) use '/boot/grub2/grub.cfg' etc.

You can also handle Linuxs that don't (by default) use Grub. As long as you can identify the location and name of the Linux kernel and initrd/initramfs then you can boot directly using something like this:

Code: Select all

  menuentry "Sample Linux, No Grub installed Yet" {
     search --set=root --fs-uuid aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee
     linux /boot/vmlinuz root=UUID=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee ro
     initrd /boot/initrd
}
This should be enough to boot the installation.. Grub can then be installed to the OS manually.

Bodge99
Post Reply

Return to “Tutorials”