How-to Boot Linux VMs using UEFI (Freenas)

There have been a number of threads were people have failed to boot a Linux VM after the installation phase using the webUI of FreeNAS 11 nightly, finding themselves stuck in the EFI shell and not knowing how to proceed nor how to avoid this happening each time their VM is started.

It has been sugested elsewhere that this is due a grub error, or a grubx64.efi file which is missing or in the wrong place, or you must create a startup.nsh file or change the boot order in the EFI shell. If your Linux install depends on grub and it has completed successfully, creating the correct EFI partition (ESP) and grubx64.efi file, then none of these suggestions are correct.

Creating a VM via the webUI in FreeNAS 11 converts to a bhyve command in the backend, saving you from using a complex string of commands at the CLI e.g:

bhyve -c 4 -m 768M -HAP \
-s 0,hostbridge \
-s 3,ahci-cd,firmware-8.7.1-amd64-netinst.iso \
-s 4,ahci-hd,debianbox.img \
-s 5,virtio-net,tap1 \
-s 29,fbuf,tcp=,w=800,h=600,wait \
-s 31,lpc -l com1,stdio \
-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd \

The file /usr/local/share/uefi-firmware/BHYVE_UEFI.fd provides byve with the firmware to support UEFI guests, this function is based on the OVMF tianocore project which is also used as the basis of VirtualBox’s virtual machine UEFI support. The bhyve UEFI firmware conforms to the known “Default Boot Behaviour” and looks for the file \EFI\BOOT\boot64.efi in the EFI partition of your VM. If it’s not present you end up in the EFI shell.

One simple remedy is to create this \EFI\BOOT\boot64.efi file in your VM, which is straight forward once your VM has booted.

But how do you boot your VM if you find yourself in the EFI shell at first? Just type exit at the shell prompt, and in the EFI menu system navigate to “Boot Maintenance Manager” and then select “Boot from file” to locate and select your grubx64.efi file.

As root, cd to the /boot/efi/EFI directory of your VM in order to create the new BOOT directory and copy the existing grubx64.efi to /EFI/BOOT/bootx64.efi. The end result should look like this, using Ubuntu as an example:

root@ubuntu-vm:/boot/efi# tree -L 3 .
└── EFI
├── BOOT
│ └── bootx64.efi
└── ubuntu
├── fbx64.efi
├── grub.cfg
├── grubx64.efi
├── mmx64.efi
└── shimx64.efi

3 directories, 6 files

The file bootx64.efi is a copy of the grubx64.efi in your VM.

NB: If grubx64.efi gets updated you will need to re-create bootx64.efi

Need tree installed?

tree not installed

Add repo first.

# add-apt-repository ppa:eugenesan/ppa
sudo add-apt-repository ppa:eugenesan/ppa
sudo apt-get update
sudo apt-get install tree -y

Tree is now installed.