本文转载自 halfa (opens new window) 的博文 Boot from an EFI Shell (opens new window),并进行了翻译。

今天启动 PVE 集群上的几个虚拟机的时候,出现了下图的报错。

启动错误

报错是 BdsDxe: failed to load Boot0001 "UEFI QEMU QEMU HARDDISK" from PciRoot(0x0/Pci(0x1E,0x0)/Pci(0x1,0x0)/Pci(0x5,0x0)/Scsi(0x0,0x0): Not Found.

引导失败以后,虚拟机尝试通过 PXE 引导,也失败了,最终回到了 EFI shell:

image

这台虚拟机原本应该从 VirtIO SCSI Controller 引导。图上报错看起来是因为 PCI 总线或者一个(虚拟)存储卡变化*,导致存储在 EFI NVRAM(也就是存储 UEFI 配置的地方)的引导入口(boot entry)指向了不存在的设备,所以引导失败了。

* 估计是它之前用的另一个虚拟控制器被我不小心重命名为了 VirtIO

# 解决方案(临时)

下面是手动引导 EFI 文件的办法。想要修改 EFI 配置,你可以参考 EFI shell Cheat-sheet

EFI shell 和大部分 shell 一样,可以通过 shift + pageUp / pageDown 来滚动屏幕。可以使用 exit 命令回到 EFI 管理界面,或者 reboot 命令重启。

下面的 shell 交互演示了如何加载硬盘、手动引导:

Shell>FS0:
FS0:\> ls
Directory of: FS0:\
09/22/2019 19:43 <DIR>  4,096 EFI
04/15/2020 20:51       10,668 NvVars
    1 File(s)   10,668 bytes
    1 Dir(s)
FS0:\> cd EFI
FS0:\EFI\> cd debian
FS0:\EFI\debian\> grub64.efi

# EFI shell Cheat-sheet

  • map 命令输出分区和设备的映射表(类似于 lsblk)。vol <VOL-NAME> 会输出更多信息。
  • 输出引导选项列表:
FS0:\> bcfg boot dump -b
...
Option: 06. Variable: Boot0004
  Desc    - UEFI QEMU HARDDISK QM00001
  DevPath - PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
  Optional- Y
...
  • 移动某个引导选项位置(同时顺移其它引导选项)
# 将选项 6 移动到选项 0 的位置(也就是第 1 位),同时顺移其它选项
FS0:\> bcfg boot mv 6 0
  • 移除引导选项
FS0:\> bcfg boot rm 4
  • 添加引导选项
FS0:\> bcfg boot add 1 FS0:\EFI\GRUB\grubx64.efi "GRUB"
Target = 0007.
bcfg: Add Boot0007 as 1
  • help 命令的完整输出如下:
FS0:\> cat help.txt
alias         - Displays, creates, or deletes UEFI Shell aliases.
attrib        - Displays or modifies the attributes of files or directories.
bcfg          - Manages the boot and driver options that are stored in NVRAM.
cd            - Displays or changes the current directory.
cls           - Clears the console output and optionally changes the background and foreground color.
comp          - Compares the contents of two files on a byte-for-byte basis.
connect       - Binds a driver to a specific device and starts the driver.
cp            - Copies one or more files or directories to another location.
date          - Displays and sets the current date for the system.
dblk          - Displays one or more blocks from a block device.
devices       - Displays the list of devices managed by UEFI drivers.
devtree       - Displays the UEFI Driver Model compliant device tree.
dh            - Displays the device handles in the UEFI environment.
disconnect    - Disconnects one or more drivers from the specified devices.
dmem          - Displays the contents of system or device memory.
dmpstore      - Manages all UEFI variables.
drivers       - Displays the UEFI driver list.
drvcfg        - Invokes the driver configuration.
drvdiag       - Invokes the Driver Diagnostics Protocol.
echo          - Controls script file command echoing or displays a message.
edit          - Provides a full screen text editor for ASCII or UCS-2 files.
eficompress   - Compresses a file using UEFI Compression Algorithm.
efidecompress - Decompresses a file using UEFI Decompression Algorithm.
else          - Identifies the code executed when 'if' is FALSE.
endfor        - Ends a 'for' loop.
endif         - Ends the block of a script controlled by an 'if' statement.
exit          - Exits the UEFI Shell or the current script.
for           - Starts a loop based on 'for' syntax.
getmtc        - Gets the MTC from BootServices and displays it.
goto          - Moves around the point of execution in a script.
help          - Displays the UEFI Shell command list or verbose command help.
hexedit       - Provides a full screen hex editor for files, block devices, or memory.
if            - Executes commands in specified conditions.
ifconfig      - Modifies the default IP address of the UEFI IPv4 Network Stack.
ifconfig6     - Displays or modifies IPv6 configuration for network interface.
load          - Loads a UEFI driver into memory.
loadpcirom    - Loads a PCI Option ROM.
ls            - Lists the contents of a directory or file information.
map           - Displays or defines file system mappings.
memmap        - Displays the memory map maintained by the UEFI environment.
mkdir         - Creates one or more new directories.
mm            - Displays or modifies MEM/MMIO/IO/PCI/PCIE address space.
mode          - Displays or changes the console output device mode.
mv            - Moves one or more files to a destination within or between file systems.
openinfo      - Displays the protocols and agents associated with a handle.
parse         - Retrieves a value from a standard format output file.
pause         - Pauses a script and waits for an operator to press a key.
pci           - Displays PCI device list or PCI function configuration space and PCIe extended
configuration space.
ping          - Ping the target host with an IPv4 stack.
ping6         - Ping a target machine with UEFI IPv6 network stack.
reconnect     - Reconnects drivers to the specific device.
reset         - Resets the system.
rm            - Deletes one or more files or directories.
sermode       - Sets serial port attributes.
set           - Displays or modifies UEFI Shell environment variables.
setsize       - Adjusts the size of a file.
setvar        - Displays or modifies a UEFI variable.
shift         - Shifts in-script parameter positions.
smbiosview    - Displays SMBIOS information.
stall         - Stalls the operation for a specified number of microseconds.
time          - Displays or sets the current time for the system.
timezone      - Displays or sets time zone information.
touch         - Updates the filename timestamp with the current system date and time.
type          - Sends the contents of a file to the standard output device.
unload        - Unloads a driver image that was already loaded.
ver           - Displays UEFI Firmware version information.
vol           - Displays or modifies information about a disk volume.

Help usage:help [cmd|pattern|special] [-usage] [-verbose] [-section name][-b]

Reference: GRUB/EFI examples from the Archlinux Wiki (opens new window)