1

I'm using a computer, a Dell OptiPlex 9010, which comes with UEFI firmware, but does not support booting from PCI-Express NVMe devices.

I've worked around this by using DUET to create an EFI boot partition on a USB stick, which has an NVMe driver which it loads, and then executes my OS's EFI boot program.

The commands to do this are currently entered manually. Here is the process:

  1. Computer is turned off.
  2. Insert my DUET USB stick into a USB port (I just always leave it plugged in)
  3. Turn on the computer
  4. (The UEFI is configured to always boot from that USB stick first, and ignore the boot loaders in the other drives I have plugged in)
  5. The DUET USB stick loads an EFI shell (EFI Shell version 2.31 [4.653])
  6. (The map command shows the DUET USB stick is automatically mounted at fs0:)
  7. I load the NVMe driver: load fs0:\EFI\Drivers\NvmExpressDxe-64.efi
  8. I trigger a refresh of volume mappings with map -r, this command completes successfully without any issues.
  9. (My NVMe volume is now listed, sometimes as fs1: but also sometimes as fs0:)
  10. I boot into Windows by running: fs1:\EFI\Boot\Bootx64.efi
  11. Windows' startup screen appears and the computer resumes to boot Windows

I tried to automate this by putting the commands inside a startup.nsh script (the EFI equivalent of DOS' autoexec.bat).

My script is this:

echo Step 1
load fs0:\EFI\Drivers\NvmExpressDxe-64.efi
echo Step 2
map -r
echo Step 3
fs0:
echo Step 4
fs0:\EFI\Boot\Bootx64.efi
echo Step 5

(This script uses fs0: instead of fs1: because when startup.nsh runs, my NVMe drive is remapped to fs0:, but when I run the commands interactively instead it's mapped to fs1:. I don't know why or how this happens).

When I boot up and let the shell execute startup.nsh I get this output:

startup.nsh> Step 1
startup.nsh> load fs0:\EFI\Drivers\NvmExpressDxe-64.efi
load: Image fs0:\EFI\Drivers\NvmExpressDxe-64.efi loaded at D7C3F000 - Success
startup.nsh> Step 2
startup.nsh> map -r
Device mapping table
  fs0  :PciRoot(0x0)/Pci(0x1c,0x4)/...
  fs1  :PciRoot(0x0)/Pci(0x1c,0x4)/...
  blk0 :PciRoot(0x0)/Pci(0x1c,0x4)/...
  ...
Shell: Cannot read from file - No Media
Shell> _

So when map -r is executed from within startup.nsh it runs, but then fails with the "Cannot read from file - No Media" error, and it then aborts executing the rest of the script (as there is no echo Step 3 output), however if I manually type in the fs0:\EFI\Boot\Bootx64.efi command then Windows loads fine.

I looked at the EFI Shell Commands documentation and I don't see any command like try or on error resume next or on error goto :label - so the script is doomed to fail.

1

I can confirm that the map -r breaks the startup script.

This happens because the remapping changes the location of the script and the shell cannot read the next command to execute. You can fix this by changing the EFI shell mode and than use update method of the maping.

In short, instead of map -r, try this:

connect -r
set -v efishellmode 1.1.2
map -u
  • Thank you - this worked! (Sorry for taking 2 months to test it out!) – Dai Aug 26 '17 at 3:40
0

IMHO, your approach is overly complex. You're using your computer's built-in EFI's CSM to run a second EFI implementation from an external disk and then loading an EFI driver in the second EFI implementation. Several alternatives occur to me:

  • You could run an EFI shell in your computer's native EFI and run the script from there to load the EFI driver. This cuts out the CSM and the second EFI implementation, which should reduce boot time and improve reliability. That said, this option would most likely produce the same problem you're seeing.
  • You could run my rEFInd in the computer's native EFI and configure your driver as one that rEFInd loads automatically. A big caveat with this is that rEFInd's driver-loading code has been well-tested for filesystems but not with other types of drivers, so I can't promise it would load your driver. Also, even if it did load your driver, you might run into a problem similar to the one you're already encountering.
  • You could put your boot loader(s), and if necessary your OS kernel(s), on media that your native EFI can read, thus bypassing the need for an NVMe driver. Since you're already using a USB flash drive for DUET, you could use that; or presumably your computer supports other types of hard disk, so you could use one of them, even if it's not your primary storage type. As I'm not a Windows expert, I can't suggest specifically how to lay Windows out to do this.

That said, I don't know the answer to your direct question. It's clearly caused by the remapping of devices when you load the new driver, which "pulls the rug out" from the shell.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.