When I got my HP ML110 Gen9 working as a workstation I initially was under the impression that boot wasn’t supported on NVMe and booted it from USB. I found USB booting with legacy boot to be unreliable so decided to try EFI booting and noticed that the NVMe devices were boot candidates with UEFI. Making one of them bootable was more complex than expected because no-one seems to have documented such things. So here’s my documentation, it’s not great but this method has worked once for me.
Before starting major partitioning work it’s best to run “parted -l and save the output to a file, that can allow you to recreate partitions if you corrupt them. One thing I’m doing on systems I manage is putting “@reboot /usr/sbin/parted -l > /root/parted.log” in the root crontab, then when the system is backed up the backup server gets any recent changes to partitioning (I don’t backup /var/log on all my systems).
Firstly run parted on the device to create the EFI and /boot partitions, note that if you want to copy and paste from this you must do so one line at a time, a block paste seemed to confuse parted.
mklabel gpt mkpart EFI fat32 1 99 mkpart boot ext3 99 300 toggle 1 boot toggle 1 esp p # Model: CT1000P1SSD8 (nvme) # Disk /dev/nvme1n1: 1000GB # Sector size (logical/physical): 512B/512B # Partition Table: gpt # Disk Flags: # # Number Start End Size File system Name Flags # 1 1049kB 98.6MB 97.5MB fat32 EFI boot, esp # 2 98.6MB 300MB 201MB ext3 boot q
Here are the commands needed to create the filesystems and install the necessary files. This is almost to the stage of being scriptable. Some minor changes need to be made to convert from NVMe device names to SATA/SAS but nothing serious.
mkfs.vfat /dev/nvme1n1p1 mkfs.ext3 -N 1000 /dev/nvme1n1p2 file -s /dev/nvme1n1p2 | sed -e s/^.*UUID/UUID/ -e "s/ .*$/ \/boot ext3 noatime 0 1/" >> /etc/fstab file -s /dev/nvme1n1p1 | tr "[a-f]" "[A-F]" |sed -e s/^.*numBEr.0x/UUID=/ -e "s/, .*$/ \/boot\/efi vfat umask=0077 0 1/" >> /etc/fstab # edit /etc/fstab to put a hyphen between the 2 groups of 4 chars for the VFAT filesystem UUID mount /boot mkdir -p /boot/efi /boot/grub mount /boot/efi mkdir -p /boot/efi/EFI/debian apt install efibootmgr shim-unsigned grub-efi-amd64 cp /usr/lib/shim/* /usr/lib/grub/x86_64-efi/monolithic/grubx64.efi /boot/efi/EFI/debian file -s /dev/nvme1n1p2 | sed -e "s/^.*UUID=/search.fs_uuid /" -e "s/ .needs.*$/ root hd0,gpt2/" > /boot/efi/EFI/debian/grub.cfg echo "set prefix=(\$root)'/boot/grub'" >> /boot/efi/EFI/debian/grub.cfg echo "configfile \$prefix/grub.cfg" >> /boot/efi/EFI/debian/grub.cfg grub-install update-grub
If someone would like to make a script that can handle the different partition names of regular SCSI/SATA disks, NVMe, CCISS, etc then that would be great. It would be good to have a script in Debian that creates the partitions and sets up the EFI files.
If you want to have a second bootable device then the following commands will copy a GPT partition table and give it new UUIDs, make very certain that $DISKB is the one you want to be wiped and refer to my previous mention of “parted -l“. Also note that parted has a rescue command which works very well.
sgdisk /dev/$DISKA -R /dev/$DISKB sgdisk -G /dev/$DISKB
To backup a GPT partition table run a command like this. Note that if sgdisk is told to backup a MBR partitioned disk it will say “Found invalid GPT and valid MBR; converting MBR to GPT forma” which is probably a viable way of converting MBR format to GPT.
sgdisk -b sda.bak /dev/sda
You may also want to copy grubx64.efi to UEFI default boot path $ESP/EFI/BOOT/BOOTX64.EFI that way if for some reason your bios decides to forget all setting then the system will still be bootable.
https://wiki.debian.org/UEFI#Booting_from_removable_media