When upgrading hardware, some newer hardware tends to be allergic towards old BIOS booting. Fortunately converting is relatively simple once you figure out all the pieces needed.
The main points are:
1. Boot off a rescue CD, add EFI partition, mount filesystems
2. Remove grub-pc
3. Install grub-efi
Here's a closer look at it:
1. Boot off a rescue CD
I use SystemRescueCD 9 here, but probably any version works. Important: boot the CD image in EFI mode! Otherwise you won't be able to add grub-efi to the EFI boot menu and the system won't boot.
After it has booted, we need a directory for our root partition. I'll use /mnt/target here, the system's root is assumed /dev/sda1, use tools like lsblk and blkid to identify the correct one in yours.
We will need access to EFI parameter store, so we first need to modprobe efivarfs.
First verify with a partition editor, such as cfdisk that the disk uses GPT partition scheme. If not, you have to convert it first in-place with gdisk /dev/sda. Gdisk will load the MBR partition table, after which you can use the w-command to write the GPT partition table over it. This does not affect the partitions themselves or the data on them.
Grub's EFI parts needs a vfat partition to live in. It only needs some megabytes, 200 megabyte partition is enough. Partition type for it is EFI System. One quick hack is to make the swap partition this much smaller. It can be then formatted to vfat with mkfs.vfat. The freshly created partition will be /dev/sda3 here.
Next we mount the system root directory and bind-mount the system directories from the live CD's ramdisk root. Without these bind mounts grub-install won't work. We also mount efivarfs.
mount /dev/sda1 /mnt/target
mkdir -v /mnt/target/boot/efi
mount /dev/sda3 /mnt/target/boot/efi
mount -o bind /sys /mnt/target/sys
mount -o bind /proc /mnt/target/proc
mount -o bind /dev /mnt/target/dev
mount -o bind /dev/pts /mnt/target/dev/pts
mount -t efivarfs none /mnt/target/sys/firmware/efi/efivars
Now that we've gotten everything mounted, we chroot into the real system.
chroot /mnt/target /bin/bash
Hopefully we now find ourselves inside the target system. First thing we do here is to add the new efi partition to the /etc/fstab.
/dev/sda3 /boot/efi vfat umask=0077 0 0
The old grub conflicts with the grub-efi, so we get rid of it:
apt --purge remove grub-pc
It'll most likely remove its dependencies as well.
3. Install grub-efi
apt install grub-efi shim-signed
It'll also install couple of handy utilities for poking EFI, like efibootmgr. The shim-signed package makes it possible to use secure boot.
Next we need to install grub's files on the freshly created vfat partition. Note that this command does not take the partition, but the device where the root drive is installed. Since the root here was /dev/sda1, it's just /dev/sda.
grub-install /dev/sda
Look at carefully what it says. If it errors out, there are couple of things that might have been wrong. First thing to check with errors is if you actually booted in EFI mode or BIOS. If it complains about not being able to modify EFI variables, the efivarfs module is missing or it was not mounted.
If everything went okay, the files EFI need are now placed on the vfat partition, but we still need the menu entry for the OS. Update-grub does this for us. We also need to update the existing initramfs.
update-grub
update-initramfs -u
It should mention that it adds the boot menu entry. We can then use efibootmgr to investigate:
efibootmgr
Spot the Debian or Ubuntu entry in the list and see that it's listed in the BootOrder. The other options vary depending on the motherboard or virtualization platform.
If the efibootmgr shows the entry, you're now ready to boot. Exit from the chroot and reboot the machine. You should be greeted with grub-efi's boot menu now.