将 AfuEfiX64.efi BIOS 升级程序作为启动项运行,而不是通过 UEFI shell,启用安全启动

问题描述 投票:0回答:0

通常,要使用 AMI 的 AfuEfiX64.efi BIOS 升级程序,您必须通过 UEFI shell 运行 .efi 文件。这适用于禁用安全启动,但启用安全启动时无法访问 UEFI shell,因此我必须通过启动条目运行此 EFI 文件,而不是使用

efibootmgr
动态创建启动条目,如下所示:

# this creates the boot entry with the correct parameters to upgrade the BIOS
efibootmgr -C --disk /dev/nvme0n1 --part 1 --label "BiosUpgrader" --loader "\EFI\AfuEfix64Signed.efi" --unicode "fs:0/EFI/BIOS_UPDATE_FILE.BIN  /p /b /n /x /k /RLC:F"
# and then make sure it boots next time we restart
efibootmgr -n 000X # (X=number of created boot entry)

这有效并创建了引导条目,我可以像启动操作系统的引导加载程序一样运行它。当我尝试从 BIOS 固件界面启动到这个创建的启动项时,即使禁用了安全启动,屏幕也会变暗一秒钟,然后返回到固件界面。

我相信这可能会发生,因为 EFI 应用程序可能需要在 UEFI shell 中运行?为了解决这个问题,我创建了自己的 EFI 应用程序,它打开一个 EFI shell,然后调用一个 .nsh 脚本,该脚本使用正确的参数运行 AfuEfiX64.efi 程序:

#include <Guid/FileInfo.h>
#include <Library/FileHandleLib.h>
#include <Library/PcdLib.h>
#include <Library/ShellLib.h>
#include <Library/UefiApplicationEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/UefiShellLib/UefiShellLib.h>
#include <Protocol/EfiShellEnvironment2.h>
#include <Protocol/EfiShellInterface.h>
#include <Protocol/LoadedImage.h>
#include <Protocol/Shell.h>
#include <Protocol/ShellParameters.h>
#include <Uefi.h>

EFI_STATUS
EFIAPI
UefiMain(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable) {
  // Get the loaded image protocol for the current image
  EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
  EFI_STATUS Status = gBS->HandleProtocol(
      ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&LoadedImage);
  if (EFI_ERROR(Status)) {
    Print(L"Failed to get loaded image protocol: %r\n", Status);
    gBS->Stall(1000000);
    return Status;
  }

  // initialize the shell
  Status = ShellInitialize();
  if (EFI_ERROR(Status)) {
    Print(L"Failed to initialize the shell: %r\n", Status);
    gBS->Stall(1000000);
    // return Status;
  }

  // Check whether the UEFI Shell protocol is present
  Status = gBS->LocateProtocol(&gEfiShellProtocolGuid, NULL,
                               (VOID **)&gEfiShellProtocol);
  if (EFI_ERROR(Status)) {
    Print(L"The UEFI Shell is not installed on this system: %r\n", Status);
    gBS->Stall(1000000);
    // return Status;
  }

  // The UEFI Shell is installed on this system, run the script
  ShellExecute(ImageHandle, L"bios-update.nsh", FALSE, NULL, &Status);
  if (EFI_ERROR(Status)) {
    Print(L"Failed to run script: %r\n", Status);
    // wait 5 seconds
    gBS->Stall(5000000);
    return Status;
  }

  return EFI_SUCCESS;
}

这似乎不起作用:

  • 我收到错误消息“UEFI Shell 未安装在此系统上:未找到”
  • 继续时,ShellExecute 函数返回“无法运行脚本:未找到”,无论我在
    L"<command>"
    参数中输入什么
  • 如果我尝试通过 UEFI shell 执行上述 EFI 应用程序,什么也没有发生,也没有输出任何东西。

所以这是我的问题:

  1. 有没有更好的方法直接运行 AfuEfiX64.efi 程序,而无需创建我自己的 EFI 文件将其包装在 UEFI shell 中?
  2. 有没有办法获得更详细的信息,说明为什么 EFI 程序无法作为引导条目运行?
  3. 从启动项启动时甚至可以使用 ShellExecute(而不是通过 UEFI shell)吗?还是我的脚本有问题?
c bios uefi edk2
© www.soinside.com 2019 - 2024. All rights reserved.