我正在研究 EFI 变量,/sys/firmware/efi/efivars
在尝试解析其内容时偶然发现了一些我不理解的东西。根据最新规格EFI 文件(第 3.3 节全局定义变量),每个Boot####
变量包含一个struct
描述EFI_LOAD_OPTION
(第 3.1.3 节加载选项)。该结构(据称)是
struct efi_device_path_protocol {
uint8_t type;
uint8_t stype;
uint8_t length[2];
}
struct efi_load_option {
uint36_t attributes;
uint16_t file_path_list_length;
char16_t description[];
efi_device_path_protocol file_path_list[];
uint8_t optional_data[];
}
我的系统中的一个hexdump
随机变量产生Boot####
00000000 07 00 00 00 01 00 00 00 0d 00 55 00 45 00 46 00 |..........U.E.F.|
00000010 49 00 3a 00 52 00 65 00 6d 00 6f 00 76 00 61 00 |I.:.R.e.m.o.v.a.|
00000020 62 00 6c 00 65 00 20 00 44 00 65 00 76 00 69 00 |b.l.e. .D.e.v.i.|
00000030 63 00 65 00 00 00 05 01 09 00 82 00 00 00 00 7f |c.e.............|
00000040 ff 04 00 |...|
00000043
我期待着
- 前 4 个字节作为属性:这是可以的,在这种情况下预期的值为 7;
- 接下来的 2 个字节是整数,告诉我字段的长度(以字节为单位)
field_path_list
:该字段是可选的,但这里说它的长度为 1 个字节。但struct
据说它至少有 4 个字节长。什么? - 接下来的字节串(直到出现空字符)都是
char16_t
字符,用于编码此启动选项的描述。char16_t
但field_path_list_length
是一个空字符,所以没有描述?
但那里是描述: 。但只有当我跳过和 之间看起来像 的实际开头的UEFI:Removable Device
4 个字节时,这才是正确的。field_path_list_length
description[]
我的固件是否不符合要求?我是否遗漏了什么?那 4 个字节是什么?
答案1
在/sys/firmware/efi/efivars中,前四个字节是属性对于变量本身,对应于Attributes
GetVariable() 返回的参数(请参阅 8.2 变量服务用于标志定义)。Data
变量的实际值从 4 个字节后开始。
请注意,您通常不会将 0x7 作为 efi_load_option.attributes,因为第 3.1.3 节中没有位 0x4 的定义。
(另请注意结构 efi_device_path_protocol仅定义每个路径项的标题 - 根据类型和子类型会有其他字段,因此文件路径列表[]与常规 C 数组并不完全相同,并且整个结构也不完全相同于常规 C 结构。
换句话说,你正在查看的是:
struct {
uint32_t Attributes = 0x00000007, /* NON_VOLATILE | BOOTSERVICE_ACCESS | RUNTIME_ACCESS */
Data[] = (struct efi_load_option) {
uint32_t attributes = 0x00000001, /* ACTIVE */
uint16_t file_path_list_length = 0x000d, /* 13 */
char16_t description[] = L"UEFI:Removable Device",
file_path_list[] = {
{
uint8_t type = 0x05, /* BIOSBootDevice - table 44 */
uint8_t subtype = 0x01, /* BiosBootDevice */
uint16_t length = 0x0009, /* 4 (header) + 5 (data) */
/* table 101 */
uint16_t device_type = 0x0082, /* unknown reserved value */
uint16_t status_flag = 0x0000,
char description_string[] = "",
},
{
uint8_t type = 0x7f, /* EndOfDevicePath - table 44 */
uint8_t subtype = 0xff, /* EndEntireDevicePath - table 45 */
uint16_t length = 0x0004, /* 4 (header) + 0 (data) */
/* no data */
},
},
uint8_t optional_data[] = {},
}
}