EFI 启动 shell 脚本中的错误处理

EFI 启动 shell 脚本中的错误处理

我正在使用一台计算机,戴尔 OptiPlex 9010,它带有 UEFI 固件,但不支持从 PCI-Express NVMe 设备启动。

我已经通过使用解决了这个问题二重唱在 USB 记忆棒上创建一个 EFI 启动分区,该分区具有可加载的 NVMe 驱动程序,然后执行我的操作系统的 EFI 启动程序。

目前,执行此操作的命令是手动输入的。流程如下:

  1. 计算机已关闭。
  2. 将我的 DUET USB 插入 USB 端口(我总是把它插着)
  3. 打开电脑
  4. (UEFI 配置为始终首先从该 USB 驱动器启动,并忽略我插入的其他驱动器中的引导加载程序)
  5. DUET USB 驱动器加载 EFI shell(EFI Shell version 2.31 [4.653]
  6. (该map命令显示 DUET USB 驱动器已自动安装在fs0:
  7. 我加载了 NVMe 驱动程序:load fs0:\EFI\Drivers\NvmExpressDxe-64.efi
  8. 我使用 触发卷映射的刷新map -r,此命令成功完成,没有任何问题。
  9. (我的 NVMe 卷现在已列出,有时为fs1:但有时为fs0:
  10. 我通过运行以下命令启动 Windows:fs1:\EFI\Boot\Bootx64.efi
  11. 出现 Windows 启动屏幕,计算机恢复启动 Windows

我尝试通过将命令放入startup.nsh脚本(EFI 中相当于 DOS autoexec.bat)来实现自动化。

我的脚本是这样的:

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

(此脚本使用fs0:而不是fs1:因为在startup.nsh运行时,我的 NVMe 驱动器被重新映射到fs0:,但是当我以交互方式运行命令时它被映射到fs1:。我不知道为什么或如何发生这种情况)。

当我启动并让 shell 执行时,startup.nsh我得到以下输出:

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> _

因此,当map -r从内部执行时startup.nsh,它会运行,但随后因“无法从文件读取 - 没有媒体”错误而失败,然后它会中止执行脚本的其余部分(因为没有echo Step 3输出),但是如果我手动输入fs0:\EFI\Boot\Bootx64.efi命令则 Windows 可以正常加载。

我查看了 EFI Shell 命令文档,没有看到任何类似tryon error resume next或的命令on error goto :label- 因此该脚本注定会失败。

答案1

我可以确认这map -r会破坏启动脚本。

发生这种情况是因为重新映射改变了脚本的位置,并且 shell 无法读取要执行的下一个命令。您可以通过更改 EFI shell 模式并使用映射的更新方法来解决此问题。

简而言之,不要这样做,而是map -r尝试这样做:

connect -r
set -v efishellmode 1.1.2
map -u

答案2

恕我直言,您的方法过于复杂。您正在使用计算机内置的 EFI 的 CSM 从外部磁盘运行第二个 EFI 实现,然后在第二个 EFI 实现中加载 EFI 驱动程序。我想到几种替代方案:

  • 您可以在计算机的原生 EFI 中运行 EFI shell,然后从那里运行脚本来加载 EFI 驱动程序。这样可以省去 CSM 和第二个 EFI 实现,从而缩短启动时间并提高可靠性。不过,此选项很可能会产生您看到的相同问题。
  • 你可以运行我的重新索引在计算机的原生 EFI 中,并将您的驱动程序配置为 rEFInd 自动加载的驱动程序。一个很大的警告是,rEFInd 的驱动程序加载代码已经针对文件系统进行了充分测试,但没有针对其他类型的驱动程序进行充分测试,所以我不能保证它会加载您的驱动程序。此外,即使它确实加载了您的驱动程序,您也可能会遇到与您已经遇到的问题类似的问题。
  • 您可以将引导加载程序(如果需要,还可以将操作系统内核)放在本机 EFI 可以读取的介质上,这样就无需使用 NVMe 驱动程序。由于您已经在使用 USB 闪存驱动器进行 DUET,因此您可以使用它;或者您的计算机可能支持其他类型的硬盘,因此您可以使用其中一种,即使它不是您的主要存储类型。由于我不是 Windows 专家,我无法具体建议如何布局 Windows 来执行此操作。

话虽如此,我不知道你直接提出的问题的答案。这显然是由于加载新驱动程序时重新映射设备而导致的,这会“拉走”外壳的地毯。

相关内容