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.