3 - Boot Manager
UEFI Boot Manager 是一个固件政策引擎,它会去通过读取 NVRAM 中的全局变量(也就是 Boot Option 对应的 BootXXXX)来获取可以 boot 的启动项,然后根据中间的信息来加载 UEFI driver 或者 UEFI Image.同时在这个加载过程中若是遇到异常情况,也可也实现其他异常处理机制(比如启动完所有的启动项,都失败则进入 setup 界面)。
Boot Option 主要是有以下特性:
- Boot Manager 是通过 NVRAM 中获取的
- 其他对于 BootOption 的修改,只是针对于下一次重启,也就是下次重启之后, bootoption 会被根据当前配置重新创建。
- BootOption 中间包含的信息可以是:
- 可以从什么地方去进行 boot 引导
- 包含对应包含 UEFI Driver 或者 UEFI Image 的硬件指针
- 可以包含系统分区的目录的路径以及其他配置目录
- 同时包含便于人读取的描述符
结构体如下:
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;
NVRAM还可以包含直接传递给UEFI映像的加载选项。平台固件不知道 BootOption 中包含的内容。BootOption由高级软件在写入全局NVRAM变量以设置平台固件启动策略时设置。如果操作系统内核的位置与UEFI操作系统加载程序的位置不同,则可以使用此信息来定义操作系统内核的位置。(可以理解为系统 bootx64.efi 在执行的时候,会去创建一个 Bootoption,名字就是系统的名字)。
3.1 Firmware Boot Manager
Firmware Boot Manager是符合此规范的固件中的一个组件,它决定应该显式加载哪些驱动程序和应用程序以及何时加载。一旦兼容固件被初始化,它就会将控制传递给引导管理器。然后,Boot Manager负责确定要加载什么,以及可能需要与用户进行交互才能做出这样的决定。
boot manager所采取的操作取决于系统类型和系统设计者设置的策略。对于允许安装新的引导变量的系统,引导管理器必须自动或根据加载项的请求,初始化至少一个系统控制台,以及执行主引导目标中指示的所有必要的设备初始化。对于这样的系统,引导管理器还需要遵循BootOrder变量中设置的优先级
特别是,可能的实现选项可能包括任何与引导有关的控制台接口、 引导选择的集成平台管理,以及可能通过引导管理器集成到系统中的其他内部 应用程序或恢复驱动程序的知识
3.1.1 Boot Manager Programming
与引导管理器的编程交互是通过全局定义的变量完成的。在初始化时,引导管理器读取包含 中UEFI环境变量所有 Bootoption 的值。通过使用SetVariable()函数,可以修改包含这些Bootoption variable 的数据。这些修改保证在下一次系统启动开始后生效。但是, Boot Manager实现可以选择使对影响的变量的所有后续访问的更改立即生效。
在 UEFI 中可以 boot 的启动项的变量可以是:Boot####, Driver####, SysPrep####, OsRecovery#### 或者 PlatformRecovery#### variable,中####是一个标识符,必须是整数而且是唯一的,范围是 0000-FFFF。
BootManager 先会去加载包含Driver####的 DriverOrder,然后加载包含 Boot####的 BootOrder。在创建 Boot####的时候同步会将 Boot####添加到 BootOrder.
在加载启动项的时候,BootManger 会去轮询所有的 BootOption,直到返回是EFI_SUCCESS,然后显示启动菜单;若是没有一个返回EFI_SUCCESS,则会处理 recovery boot option.
同时启用安全启动时,UEFI引导管理器的行为会受到影响,在启动时会对对应的启动项检查,看是否有签名或者在白名单内等等行为。