Skip to content

Instantly share code, notes, and snippets.

@rgl
Last active March 24, 2023 04:27
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rgl/a84399e14469a4175291a22d018bc0c6 to your computer and use it in GitHub Desktop.
Save rgl/a84399e14469a4175291a22d018bc0c6 to your computer and use it in GitHub Desktop.
BIOS: Convert from MBR to GTP

MBR to GPT Conversion

This is a three step procedure:

  1. Use gdisk to convert the partition type from MBR to GPT (without data loss).
  2. Use gdisk to add a new BIOS boot partition (EF02 type).
  3. Use grub-install to install the boot loader into the new BIOS boot partition.

MBR to GPT

Install the required tools:

sudo -i
apt-get update
apt-get install -y gdisk grub-pc

Use gdisk to convert the partition from MBR to GPT and add a new BIOS boot partition (EF02 type):

root@example:~# gdisk /dev/vda
GPT fdisk (gdisk) version 1.0.5

Partition table scan:
  MBR: MBR only
  BSD: not present
  APM: not present
  GPT: not present


***************************************************************
Found invalid GPT and valid MBR; converting MBR to GPT format
in memory. THIS OPERATION IS POTENTIALLY DESTRUCTIVE! Exit by
typing 'q' if you don't want to convert your MBR partitions
to GPT format!
***************************************************************


Command (? for help): p
Disk /dev/vda: 125829120 sectors, 60.0 GiB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): DB422890-1328-483C-BC2F-59E822704FF1
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 125829086
Partitions will be aligned on 2048-sector boundaries
Total free space is 4029 sectors (2.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048       125827071   60.0 GiB    8300  Linux filesystem

Command (? for help): n
Partition number (2-128, default 2): 
First sector (34-125829086, default = 125827072) or {+-}size{KMGTP}: 34
Last sector (34-2047, default = 2047) or {+-}size{KMGTP}: 2047
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): ef02
Changed type of partition to 'BIOS boot partition'

Command (? for help): p
Disk /dev/vda: 125829120 sectors, 60.0 GiB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): DB422890-1328-483C-BC2F-59E822704FF1
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 125829086
Partitions will be aligned on 2048-sector boundaries
Total free space is 2015 sectors (1007.5 KiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048       125827071   60.0 GiB    8300  Linux filesystem
   2              34            2047   1007.0 KiB  EF02  BIOS boot partition

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/vda.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or kpartx(8)
The operation has completed successfully.

Than, re-scan the partition table:

root@example:~# partprobe /dev/vda

root@example:~# ll /dev/vda*
brw-rw---- 1 root disk 252, 0 jun  9 08:04 /dev/vda
brw-rw---- 1 root disk 252, 1 jun  9 08:04 /dev/vda1
brw-rw---- 1 root disk 252, 2 jun  9 08:04 /dev/vda2

Install grub:

root@example:~# grub-install /dev/vda
Installing for i386-pc platform.
Installation finished. No error reported.

And finally reboot:

root@example:~# reboot

MBR to GPT with partition number re-ordering

Make sure your machine /etc/fstab is locating all partitions by UUID (because the partition numbers will be renumbered), for example:

UUID=20c6c154-35dd-4054-b352-7c219c6ad947 / ext4 errors=remount-ro 0 1

Boot your machine from the rescue iso at https://github.com/rgl/debian-live-builder-vagrant/releases.

TODO Probably we should check for the FS consistency before doing anything else.

Install the required tools:

sudo -i
apt-get update
apt-get install -y gdisk grub-pc

List the current partitions:

gdisk -l /dev/vda

In this example, there is a single MBR partition:

GPT fdisk (gdisk) version 1.0.5

Partition table scan:
  MBR: MBR only
  BSD: not present
  APM: not present
  GPT: not present


***************************************************************
Found invalid GPT and valid MBR; converting MBR to GPT format
in memory. 
***************************************************************

Disk /dev/vda: 125829120 sectors, 60.0 GiB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 72848D5E-494B-467C-B34F-1D1D966F3E31
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 125829086
Partitions will be aligned on 2048-sector boundaries
Total free space is 4029 sectors (2.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048       125827071   60.0 GiB    8300  Linux filesystem

And since there is room to install grub (it requires less than 1 MB) between the First usable sector to the first partition Start (sector), we can proceed.

Start gdisk in the target disk, and delete all partitions with the d command:

root@example:~# gdisk /dev/vda
GPT fdisk (gdisk) version 1.0.5

Partition table scan:
  MBR: MBR only
  BSD: not present
  APM: not present
  GPT: not present


***************************************************************
Found invalid GPT and valid MBR; converting MBR to GPT format
in memory. THIS OPERATION IS POTENTIALLY DESTRUCTIVE! Exit by
typing 'q' if you don't want to convert your MBR partitions
to GPT format!
***************************************************************


Command (? for help): d
Using 1

Command (? for help): p
Disk /dev/vda: 125829120 sectors, 60.0 GiB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 99D5C012-F5F5-4E6C-9CF4-F079C63C2218
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 125829086
Partitions will be aligned on 2048-sector boundaries
Total free space is 125829053 sectors (60.0 GiB)

Number  Start (sector)    End (sector)  Size       Code  Name

Command (? for help): 

Configure gdisk partition alignment to 1 (to allow us to create the unaligned grub/bios partition) and create the EF02 BIOS boot partition partition type:

Command (? for help): x

Expert command (? for help): l
Enter the sector alignment value (1-65536, default = 2048): 1

Expert command (? for help): m

Command (? for help): n
Partition number (1-128, default 1): 
First sector (34-125829086, default = 34) or {+-}size{KMGTP}: 34
Last sector (34-125829086, default = 125829086) or {+-}size{KMGTP}: 2047
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): ef02
Changed type of partition to 'BIOS boot partition'

Command (? for help): p
Disk /dev/vda: 125829120 sectors, 60.0 GiB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 99D5C012-F5F5-4E6C-9CF4-F079C63C2218
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 125829086
Partitions will be aligned on 1-sector boundaries
Total free space is 125827039 sectors (60.0 GiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              34            2047   1007.0 KiB  EF02  BIOS boot partition

Command (? for help): 

Revert the partition alignment to the default value:

Command (? for help): x

Expert command (? for help): l
Enter the sector alignment value (1-65536, default = 2048): 

Expert command (? for help): m

Command (? for help):

Create the root partition, in the same start sector as before, AND in the same (OR higher) end sector:

Command (? for help): n
Partition number (2-128, default 2): 
First sector (2048-125829086, default = 2048) or {+-}size{KMGTP}: 
Last sector (2048-125829086, default = 125829086) or {+-}size{KMGTP}: 
Current type is 8300 (Linux filesystem)
Hex code or GUID (L to show codes, Enter = 8300): 
Changed type of partition to 'Linux filesystem'

Command (? for help): p
Disk /dev/vda: 125829120 sectors, 60.0 GiB
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): D1B54434-B18B-44D4-8000-10CF72B734A3
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 125829086
Partitions will be aligned on 2048-sector boundaries
Total free space is 0 sectors (0 bytes)

Number  Start (sector)    End (sector)  Size       Code  Name
   1              34            2047   1007.0 KiB  EF02  BIOS boot partition
   2            2048       125829086   60.0 GiB    8300  Linux filesystem

Command (? for help): 

NB The End (sector) is now higher (125829086) than before (125827071). This is only a problem when its lower; which is a no go and you should abort this whole convertion.

If all looks good, write the changes to the disk:

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/vda.
The operation has completed successfully.

Mount your root/boot partition (its now in vda2):

root@localhost:~# mount /dev/vda2 /mnt

And ensure there's a boot/grub directory:

root@localhost:~# ll /mnt/boot/
total 69232
drwxr-xr-x  3 root root     4096 May 20 16:04 ./
drwxr-xr-x 19 root root     4096 Jun  8 18:32 ../
-rw-------  1 root root  4759819 Apr 14 12:19 System.map-5.4.0-110-generic
-rw-r--r--  1 root root   237975 Apr 14 12:19 config-5.4.0-110-generic
drwxr-xr-x  4 root root     4096 May 20 16:04 grub/
lrwxrwxrwx  1 root root       28 May 20 15:57 initrd.img -> initrd.img-5.4.0-110-generic
-rw-r--r--  1 root root 52201153 May 20 16:04 initrd.img-5.4.0-110-generic
lrwxrwxrwx  1 root root       28 May 20 15:57 initrd.img.old -> initrd.img-5.4.0-110-generic
lrwxrwxrwx  1 root root       25 May 20 15:57 vmlinuz -> vmlinuz-5.4.0-110-generic
-rw-------  1 root root 13668608 Apr 14 12:56 vmlinuz-5.4.0-110-generic
lrwxrwxrwx  1 root root       25 May 20 15:57 vmlinuz.old -> vmlinuz-5.4.0-110-generic

Install grub:

TODO Most probably, we should have used grub-install from mounted distribution, from a chroot. Feel free to contribute that part :-)

root@localhost:~# grub-install --boot-directory=/mnt/boot /dev/vda
Installing for i386-pc platform.
Installation finished. No error reported.

TODO Probably we should resize the FS to match the new sizes.

Power the machine off, re-configure it to boot from disk, and finally boot into the new system... hopefully it will work!

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