1、Boot Manager简介

UEFI Boot Manager 是一个符合UEFI规范的固件中的一个组件。它决定哪些drivers和applications在何时被加载。
当平台固件初始化完成,它将控制权转交给Boot Manager。
BootManager需要决定:

  • 加载什么?
  • 做出此类决定可能需要的与用户有何种交互?

Boot Manager 是一个可以通过修改global NVRAM variable来进行配置的固件策略引擎。
Boot Manager将尝试按global NVRAM Variable定义的顺序来加载 UEFI 驱动程序和 UEFI 应用程序(包括 UEFI OS 引导加载程序)。

2、UEFI的引导顺序

UEFI 的引导顺序包括以下内容:

  • 从global定义的 NVRAM 变量中读取Boot Order List。
    Boot Order List定义一个 NVRAM 变量顺序表。
    每个NVRAM中包含有关要引导的内容的信息。并且定义了可以向用户显示的引导选项的名称。
  • 该变量还包含指向硬件设备和该硬件上文件的指针包含要加载的 UEFI 映像的设备。
  • 该变量还可能包含操作系统分区和目录的路径以及其他配置特定目录。

3、Global Variables

变量名称

长度

描述

Boot####

NV,BS,RT

一个 启动选项。####是16进制数

BootCurrent

BS,RT

当前启动项的序号。内容为一个UINT16数。

BootNext

NV,BS,RT

下一次启动的启动选项。

BootOrder

NV,BS,RT

启动项顺序列表。由一组UINT16数据组成。

BootOptionSupport

BS,RT

boot manager支持的启动项类型。UINT32型只读。

Key####

NV,BS,RT

描述热键和Boot#### 启动项之间的关系

4、Boot Manager Capabilities

Boot Manager可以通过全局变量 BootOptionSupport 报告其能力。 如果全局变量不存在,则安装程序或应用程序必须像返回值 0 一样操作。

#define EFI_BOOT_OPTION_SUPPORT_KEY     0x00000001
#define EFI_BOOT_OPTION_SUPPORT_APP     0x00000002
#define EFI_BOOT_OPTION_SUPPORT_SYSPREP 0x00000010
#define EFI_BOOT_OPTION_SUPPORT_COUNT   0x00000300

如果EFI_BOOT_OPTION_SUPPORT_KEY被置起,则boot manager 支持用热键启动Boot####启动项。
又如EFI_BOOT_OPTION_SUPPORT_APP被置起,则boot manager支持有LOAD_OPTION_CATEGORY_APP属性的启动项。

Boot Manager可支持通过热键来启动Boot####启动项。
如果支持,则应该在BootOptionSupport全局变量中报告EFI_BOOT_OPTION_SUPPORT_KEY的能力。
Boot Manger支持从console获取按键,并且从全局变量中匹配Key####和Boot####变量,匹配到可用的启动项则立即启动它。

5、启动机制

EFI可以通过使用 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL 或 EFI_LOAD_FILE_PROTOCOL 来启动。

  • 支持EFI_SIMPLE_FILE_SYSTEM_PROTOCOL的设备必须实现文件系统协议才能使该设备可引导。
  • 如果设备不想支持一个完整的文件系统,它可能会产生一个EFI_LOAD_FILE_PROTOCOL,用于直接启动镜像。
  • Boot Manager会先尝试使用Simple File Protocol来启动,如果失败,则使用Load File Protocol。

6、如何列举启动项和启动项的设备路径

MdeModulePkg\Library\UefiBootManagerLib\BmBoot.c

**

firmware和bios区别 boot manager和bios有什么区别_加载


**

6.1、启动项的类型:

DriverOrder:已排序的驱动程序加载选项列表。(未用)
SysPrepOrder:已排序的系统准备应用程序加载选项列表。(未用)
BootOrder:有序启动选项加载列表。(主要)

6.2、枚举启动项

按以下顺序搜索所有可能的可引导媒体:
1、Removable BlockIo: 引导选项仅指向可移动介质设备,如USB密钥、DVD、软盘等。
2、Fixed BlockIo:引导选项仅指向Fixed BlockIo设备,比如硬盘。
3、Non-BlockIo SimpleFileSystem:引导选项指向支持SimpleFileSystem协议,但不支持BlockIo协议
4、LoadFile:引导选项指向支持LoadFile协议
启动项的保存进行了两层variable
首先,列举的可能的可引导媒体数量已经保存到L“BootOrder”的全球变量中
然后,每个启动项的具体结构体EFI_BOOT_MANAGER_LOAD_OPTION保存到L“Boot####” 的全球变量中。

typedef struct {
  //
  // Data read from UEFI NV variables
  //
  UINTN                             OptionNumber;       // #### numerical value, could be LoadOptionNumberUnassigned
  EFI_BOOT_MANAGER_LOAD_OPTION_TYPE OptionType;         // LoadOptionTypeBoot or LoadOptionTypeDriver
  UINT32                            Attributes;         // Load Option Attributes
  CHAR16                            *Description;       // Load Option Description
  EFI_DEVICE_PATH_PROTOCOL          *FilePath;          // Load Option Device Path
  UINT8                             *OptionalData;      // Load Option optional data to pass into image
  UINT32                            OptionalDataSize;   // Load Option size of OptionalData
  EFI_GUID                          VendorGuid;

  //
  // Used at runtime
  //
  EFI_STATUS                        Status;             // Status returned from boot attempt gBS->StartImage ()
  CHAR16                            *ExitData;          // Exit data returned from gBS->StartImage ()
  UINTN                             ExitDataSize;       // Size of ExitData
} EFI_BOOT_MANAGER_LOAD_OPTION;

6.3、接口调用流程

  • 与Boot Manager的编程交互是通过global Variable完成的。
  • 初始化时,Boot Manager读取包含 UEFI 环境变量中所有已发布加载选项的值。 通过使用 SetVariable() 函数,可以修改包含这些环境变量的数据。
  • 此类修改保证在下一次系统启动后生效。 但是,Boot Manager也可选择改进此保证,并让更改对所有后续访问影响Boot Manager行为的变量立即生效,而无需任何形式的系统重置。

    L"Boot%04x"是L"BootOrder"的子集
    1、GetEfiGlobalVariable2 (L"BootOrder", (VOID **) &BootOrder, &Size);

2、UnicodeSPrint (OptionName, sizeof (OptionName), L"Boot%04x", BootOrder【Index】);
GetVariable2 (OptionName, &gEfiGlobalVariableGuid, (VOID **) &BootOptionVar, &VariableSize);

BootOptionVar 为 启动项的具体结构体EFI_BOOT_MANAGER_LOAD_OPTION 的初始地址。
Attributes = BootOptionVar ;
Attributes : LOAD_OPTION_CATEGORY_BOOT,LOAD_OPTION_ACTIVE,LOAD_OPTION_HIDDEN
在启动前调整不同类型的内存页码,并将更新后的信息保存到变量中,以便下次启动时使用
Description = BootOptionVar + sizeof (UINT32);
Description : L"UEFI Shell";L"UEFI Hard Drive";L"Kunlun Update Tool"
DevicePath = Attributes + (BmStrSize ((CHAR16 *) BootOptionVar, VariableSize - sizeof (UINT16) - sizeof (UINT32)));
DevicePath : PciBoot(0x0) /Pci(0x1,0x1)/Pci(0x0,0x0)/Nvme(0x1,10-48-B6-11-81-30-25-00)

3 、获取启动设备的devicepath,就可以连接控制器