Skip to content

Instantly share code, notes, and snippets.

@cjyar
Last active November 26, 2024 13:44
Show Gist options
  • Save cjyar/cd5ea76a8692516767672ffc2883df92 to your computer and use it in GitHub Desktop.
Save cjyar/cd5ea76a8692516767672ffc2883df92 to your computer and use it in GitHub Desktop.
Convert a disk from MBR to GPT+UEFI, in Linux.

Before starting, make sure you have a backup, and make sure to have a linux live boot ready to rescue your system. It's easy to mess this up!

  1. Use gdisk to convert the partition table to GPT.

    gdisk /dev/sda

  2. Create the "BIOS boot" partition that GRUB needs.

    n to create a new partition. Needs to be about 1MB. You can probably squeeze this in from sectors 34-2047. Use L or l to look up the code for "BIOS boot" (ef02).

  3. Write the new partition table.

    w

  4. Reload the partition table.

    partprobe /dev/sda

  5. Re-install the GRUB boot loader using the new partition scheme.

    grub-install /dev/sda

    Optionally reboot to verify it's working. If you just need GPT and not UEFI, you can stop here.


  6. Use gdisk to add an "EFI System" partition (ESP). Officially should be 100-500MB, but mine only used 130kB. Can be anywhere on the disk, so consider putting it at the end if you're using non-resizable media like a physical disk.

    gdisk /dev/sda and use n to create the partition.

  7. Give the ESP a distinctive label without whitespace like EFI-system, because we'll reference the partition label in fstab.

    c to set the label.

  8. Write the partition table.

    w

  9. Reload the partition table.

    partprobe /dev/sda

  10. Build the filesystem for the ESP.

    mkfs -t vfat -v /dev/disk/by-partlabel/EFI-system

  11. Create the ESP mount point.

    mkdir /boot/efi

  12. Add the ESP to /etc/fstab. It should look like this:

    /dev/disk/by-partlabel/EFI-system /boot/efi vfat defaults 0 2

  13. Mount the ESP.

    mount /boot/efi

  14. Install the GRUB EFI package.

    apt install grub-efi

  15. Install the GRUB EFI bootloader onto the disk.

    grub-install --target=x86_64-efi /dev/sda

  16. Reboot.

  17. Change the BIOS from BIOS boot to UEFI boot.

  18. Use the one-time boot menu to force boot the disk. You may have to navigate to the disk -> EFI -> ubuntu -> grubx64.efi.

  19. Re-install GRUB's EFI bootloader to update the UEFI boot selector.

    grub-install

Resources:

@bjuanico
Copy link

Thanks!!! This was very helpful

@courtney-rosenthal
Copy link

Thanks for these instructions.

I ran into an error at step 15 (grub-install):

 grub-install: error: failed to get canonical path of `/cow'.

That's because I was running off a Live USB system, trying to fixup the drive at /dev/sda.

The following changes worked for me:

Step 11:

 mkdir /mnt/a
 mount /dev/sda1 /mnt/a
 mkdir /mnt/a/boot/efi

Step 12: make this change to /mnt/a/etc/fstab instead of /etc/fstab.

Step 13:

 mount /dev/disk/by-partlabel/EFI-system /mnt/a/boot/efi

Step 14: as written

Step 15:

 grub-install --recheck --root-directory=/mnt/a /dev/sda

(The "--root-directory" option is the bit to workaround the "/cow" problem.)

Step 16: as written, found Linux system correctly, booted just fine

@Banellica
Copy link

Banellica commented Nov 15, 2022

I started the procedure from an Ubuntu based PC, to which I connected a wired , (legacy BIOS bootable) USB HDD, that I would like to convert to UEFI boot. So the base computer has /dev/sda, and the disk I'd like to fix is /dev/sdb. In steps 1 to 5 I used /dev/sdb.
(I have installed grub on /dev/sdb as instructed in Step 5).
After step 5, I tried to boot from the wired USB HDD - it's not booting - stuck (shows a blinking dash).

When booting again from the parent system, and calling gdisk:

~$ sudo gdisk /dev/sdb      
GPT fdisk (gdisk) version 1.0.3
Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present
Found valid GPT with protective MBR; using GPT.

and:

Command (? for help): p
Disk /dev/sdb: 1465081856 sectors, 698.6 GiB
... ...
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 1465081822
Partitions will be aligned on 8-sector boundaries
Total free space is 2015 sectors (1007.5 KiB)
Number  Start (sector)   End (sector) Size         Code  Name
   1              2048   1465079807    698.6 GiB   8300  Linux filesystem
   2                34         2047   1007.0 KiB   EF02  BIOS boot partition

Should I follow "gogoud's" comment to this: ServeFaultStackexchange,
namely:

mkdir /mnt/newroot
mount /dev/sdb1 /mnt/newroot 
grub-install --root-directory=/mnt/newroot /dev/sdb

?

@Agab22
Copy link

Agab22 commented Nov 24, 2022

Hello thank you for the guidelines
i am into an error in step 12
mkdir /boot/efi
mkdir: cannot create directory ‘/boot/efi’: File exists
root@ford-Latitude-E6440:/home/ford# /dev/disk/by-partlabel/EFI-system /boot/efi vfat defaults 0 2
whereas /boot/efi is partition reserved for Mint Liunx 22

@SeaMonkey82
Copy link

Thanks so much for this!

@DavidPerezIngeniero
Copy link

Will I lose all existing MBR partitions with this procedure?

@cjyar
Copy link
Author

cjyar commented May 19, 2023

@DavidPerezIngeniero The goal is to keep all data, just rewriting the partition table. But do make backups before you begin!

@umatz
Copy link

umatz commented Jan 14, 2024

Thank you very much, worked perfectly for my Ubuntu 22.04 installation.

@Halbheld
Copy link

Worked without problems on Linux Mint 21.3 x86_64 in January 2024. No one-time boot menu for me.

@PeeBeerBeach
Copy link

Thank you! This helped me a lot.

@MarioFlying
Copy link

Thank you for the no-bs straight to the point list, it worked like a charm

@marco-brandizi
Copy link

Thank you so much! I've run a variant of this procedure, where I've done the GRUB (re)installations using the Boot Repair tool, Details here

@cybericius
Copy link

cybericius commented Nov 25, 2024

Wonderful, it was a great help for me. I could convert my disk!
Some tips to include in the guide, as there can be some catches.

  1. At the beginning of the guide, I would highlight the fact that it should be done on the system that boots the disk we need to convert. But! If you want to do it in a live boot or another system, go to 2.

  2. If someone is already in trouble and cannot boot for some reason from the disk or has another system where there is a system disk already - that was my case:
    Everything goes the same way as long you know which one is the disk you need to convert/fix. When you finish step 10, before you run 11, mount the root partition of the disk you want to fix:
    a) Create mnt dir: mkdir -p /mnt/fixthis
    b) Mount the partition to it (check the right disk and partition with lsblk): mount /dev/sdxy /mnt/fixthis
    c) Change the root directory to it with chroot.

  3. I have tested the following: you don't need to have anything between sectors 34-2047 as a BIOS boot partition if you only need EFI boot on modern systems. Not sure if creating the partition for BIOS boot as described in the first phase of this guide would make the disk boot in any system, be it BIOS legacy or EFI. I haven't tried that, but I'm okay with the EFI-only way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment