启动管理
启动管理(Boot Manager)是UEFI BIOS中重要的一部分,它通过一系列的变量来确定启动策略,包括:
- 执行启动还是恢复操作
- 启动顺序是如何
本文会介绍下面的内容:
- 与启动管理相关的变量
- 启动或恢复的流程策略
- 加载项结构体
- 创建加载项
注意本文只关注UEFI BIOS的启动项,涉及的是UEFI BIOS启动管理,至于Legacy的,这里不会描述。
另外,虽然是“启动管理”,但是这里的“启动”并不都是“启动操作系统”的意思,代码操作的也不叫“启动项”,而是“加载项”(Load Option),后面文档中出现的“启动”也并不一定是启动操作系统的意思,也可能仅仅是加载一个UEFI应用或UEFI驱动。
启动一般流程
以下是《UEFI Spec》中的一般规定:
- 如果
OsIndications
指定了要执行恢复操作,则不会进入通常的启动流程,而是进入恢复选项。 Driver####
会优先于Boot####
执行。- 执行Boot加载项时,先执行
BootNext
对应的加载项,然后按照BootOrder
中的顺序执行Boot####
。 - 如果
BootNext
和Boot####
中的执行都失败了,则进入启动项恢复操作,主要就是PlatformRecovery####
。
实际上真实的BIOS中,其实现可以有很多中,因此并不完全按照上述的规则。比如最后一步BootNext
和Boot####
中的执行都失败,一般会选择进入Setup,而不是PlatformRecovery####
。
启动管理变量
- 真正描述加载项的变量:
变量名 | 作用域 | 说明 |
---|---|---|
Boot#### |
NV、BS、RT | A boot load option. |
Driver#### |
NV、BS、RT | A driver load option. |
SysPrep#### |
NV、BS、RT | A System Prep application load option containing a EFI_LOAD_OPTION descriptor. |
OsRecovery#### |
NV、BS、RT | |
PlatformRecovery#### |
NV、BS、RT | Platform-specified recovery options. These variables are only modified by firmware and are read-only to the OS. |
需要注意这些变量的名称是Load Option,并不是叫启动项,虽然流程上差不多,但是很多并不是为了启动操作系统,而是一些额外的操作:
Boot####
:这些算是普通启动时的启动项。Driver####
:这些是用来加载驱动的。SysPrep####
:对应的时UEFI应用,用来为系统启动做准备的,它们会在Boot####
之前执行。PlatformRecovery####
:这些是在最后执行的,所以其它的启动都失败之后就会执行这些。
这四种类型对应到代码中:
//
// Load Option Type
//
typedef enum {
LoadOptionTypeDriver,
LoadOptionTypeSysPrep,
LoadOptionTypeBoot,
LoadOptionTypePlatformRecovery,
LoadOptionTypeMax
} EFI_BOOT_MANAGER_LOAD_OPTION_TYPE;
有几点需要注意的:
Boot####
和Driver####
是正常启动的时候都是执行的。- 启动恢复项有两类,
PlatformRecovery####
和OsRecovery####
,后者没有出现在《UEFI Spec》的“Table 10. Global Variables”中,因为它使用的是其它的GUID(称为Vendor Specific VendorGuid)。
上述的变量因为有多个,所以还有一个顺序关系,对应到一个变量:
变量名 | 作用域 | 说明 |
---|---|---|
BootOrder |
NV、BS、RT | The ordered boot option load list. |
DriverOrder |
NV、BS、RT | The ordered driver load option list. |
SysPrepOrder |
NV、BS、RT | The ordered System Prep Application load option list. |
OsRecoveryOrder |
NV、BS、RT | OS-specified recovery options. |
但是没有PlatformRecoveryOrder
,可以认为只有一个PlatformRecovery应用,所以不需要顺序吧。
另外OsRecoveryOrder
出现在《UEFI Spec》的“Table 10. Global Variables”中也比较奇怪,因为前面已经说了它应该属于VendorGuid的变量才对,并且OsRecoveryOrder
也没有出现在EDK代码中。
- 启动相关的变量:
变量名 | 作用域 | 说明 |
---|---|---|
BootCurrent |
BS、RT | The boot option that was selected for the current boot. |
BootNext |
NV、BS、RT | The boot option for the next boot only. |
BootCurrent
因为是随时可变的,所以不会存放到非易失变量中。
- 配置相关的变量:
变量名 | 作用域 | 说明 |
---|---|---|
BootOptionSupport |
BS、RT | The types of boot options supported by the boot manager. Should be treated as read-only. |
OsIndications |
NV、BS、RT | Allows the OS to request the firmware to enable certain features and to take certain actions. |
OsIndicationsSupported |
BS、RT | Allows the firmware to indicate supported features and actions to the OS. |
BootOptionSupport
对应的取值:
#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####
可以通过快捷键启动。EFI_BOOT_OPTION_SUPPORT_APP
置位表示支持启动带LOAD_OPTION_CATEGORY_APP
属性的项。EFI_BOOT_OPTION_SUPPORT_SYSPREP
置位表示支持启动SysPrep####
。EFI_BOOT_OPTION_SUPPORT_COUNT
指定了快捷键支持的按键数。
OsIndicationsSupported
表示BIOS告知OS的BIOS所支持的特性,而OsIndications
是OS告知BIOS的目前使用的特性。所以OsIndications
是OsIndicationsSupported
的一个子集,目前支持的值有:
//
// Firmware should stop at a firmware user interface on next boot
//
#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001
#define EFI_OS_INDICATIONS_TIMESTAMP_REVOCATION 0x0000000000000002
#define EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED 0x0000000000000004
#define EFI_OS_INDICATIONS_FMP_CAPSULE_SUPPORTED