How to replace UEFI Windows Bootloader with GRUB2 using Ubuntu

Context

I have Windows 11 installed in the internal SSD of a Lenovo Yoga 710 laptop and Ubuntu is installed on an external USB SSD.

Lenovo UEFIs are known by having lots of bugs and vulnerabilities. One of the bugs is that Lenovo’s UEFI won’t boot from USB drives even when it is configured in the Firmware.

That creates a scenario in which every time I wanted to boot Linux from USB I had to boot into windows, reboot into advanced boot mode, select Ubuntu, and reboot again. These are too many steps for a simple task!

So, I decided to replace Windows Bootloader with GRUB2 to be able to select USB boot or Windows boot directly when computer boots.

Next you have the steps I did to replace the Windows bootloader with Grub2 in the internal SSD.

Steps

Note: These steps have been tested in Ubuntu 22.04.1 LTS.

Windows installs the bootloader in a special partition that contains the EFI system. To locate it execute execute fdisk -l /dev/xxxx where xxxxx is the hard drive that contains Windows bootloader.

In this example Windows bootloader is in disk ‘/dev/sda’:

root@ubuntu-builder:~# fdisk -l /dev/sda
Disk /dev/sda: 465,76 GiB, 500107862016 bytes, 976773168 sectors
Disk model: Samsung SSD 860 
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 2E3258621-234G-4452-9851-5AGY98O8C0P8

Device         Start       End   Sectors  Size Type
/dev/sda1       2048   1085439   1083392  529M Windows recovery environment
/dev/sda2    1085440   1288191    202752   99M EFI System
/dev/sda3    1288192   1320959     32768   16M Microsoft reserved
/dev/sda4    1320960 877888002 876567043  418G Microsoft basic data
/dev/sda5  975566848 976771071   1204224  588M Windows recovery environment

Output shows that EFI System partition is /dev/sda2

Now let’s check if EFI partition is mounted with the command mount -l | grep /dev/yyyyy where yyyyy is EFI System partition

Example:

root@ubuntu-builder:~# mount -l | grep sda2
root@ubuntu-builder:~#

If the output of the command does not show anything it means that partition is not mounted. Create a folder and mount it.

Example:

root@ubuntu-builder:~# mkdir /mnt/efi
root@ubuntu-builder:~# mount /dev/sda2 /mnt/efi

And check it again:

root@ubuntu-builder:~# mount -l | grep sda2
/dev/sda2 on /mnt/efi type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)

Add the line GRUB_DISABLE_OS_PROBER=false at the end of the file /etc/default/grub. You can edit the file with any text editor like nano /etc/default/grub or vi /etc/default/grub

Example:

# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
#   info -f grub -n 'Simple configuration'

GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=0
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""

# To add an entry for Windows 11 using os-prober
GRUB_DISABLE_OS_PROBER=false

Now execute the command os-prober. It will detect the Windows Bootloader and prepare the configuration file for GRUB2:

root@ubuntu-builder:~# os-prober
/dev/sda2@/EFI/Microsoft/Boot/bootmgfw.efi:Windows Boot Manager:Windows:efi

Create a backup of EFI System partition with dd command: dd if=/dev/sda2 of=./efi_backup.image

Example:

root@ubuntu-builder:~# dd if=/dev/sda2 of=./efi_backup.image
202752+0 records in
202752+0 records out
103809024 bytes (104 MB, 99 MiB) copied, 0,438207 s, 237 MB/s

It’s a good idea to copy the file efi_backup.image to a pendrive to be able to restore the partition easily. See ‘Rollback’ section at the end of this page for details.

Install GRUB2 to EFI System partition with grub-install --target=x86_64-efi --efi-directory=/mnt/efi /dev/yyyyy

Example:

root@ubuntu-builder:/mnt/efi# grub-install --target=x86_64-efi --efi-directory=/mnt/efi /dev/sda2
Installing for x86_64-efi platform.
Installation finished. No error reported.

Execute grub-mkconfig -o /mnt/efi/EFI/ubuntu/grub.cfg to create GRUB2 boot menu:

Example:

root@ubuntu-builder:/mnt/efi/EFI/ubuntu# grub-mkconfig -o /mnt/efi/EFI/ubuntu/grub.cfg
Sourcing file `/etc/default/grub'
Sourcing file `/etc/default/grub.d/init-select.cfg'
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-5.15.0-43-generic
Found initrd image: /boot/initrd.img-5.15.0-43-generic
Found linux image: /boot/vmlinuz-5.15.0-30-generic
Found initrd image: /boot/initrd.img-5.15.0-30-generic
Memtest86+ needs a 16-bit boot, that is not available on EFI, exiting
Warning: os-prober will be executed to detect other bootable partitions.
Its output will be used to detect bootable binaries on them and create new boot entries.
Found Windows Boot Manager on /dev/sda2@/EFI/Microsoft/Boot/bootmgfw.efi
Adding boot menu entry for UEFI Firmware Settings ...
done

Reboot you computer and it will show the GRUB2 boot menu. In case it didn’t, do a rollback as explained next.

Rollback

Boot the computer with an Ubuntu Live USB.

Insert the pendrive with the file efi_backup.image that you created in backup step, mount it, and go to the directory where file is stored.

Next execute the command to restore the EFI Partition with the backup dd if=./efi_backup.image of=/dev/yyyyy

Example:

root@ubuntu-builder:~# dd if=./efi_backup.image of=/dev/sda2
202752+0 records in
202752+0 records out
103809024 bytes (104 MB, 99 MiB) copied, 1,52248 s, 68,2 MB/s

Reboot you computer and it will use again the Windows bootloader.