diff options
| author | Tom Rini <[email protected]> | 2026-02-15 13:28:32 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2026-02-15 13:28:32 -0600 |
| commit | ed6e970569b45c02a354f443502ed7616e0b0adf (patch) | |
| tree | def3e781dc1ef06f641997f3adbf3eaa000ccde7 /lib | |
| parent | 136faf7b0cc92af1d38b0db1bfaa5405e884ee2d (diff) | |
| parent | e54fbb2f901e897b2a2fb2a718a1ef1607b20ce5 (diff) | |
Merge tag 'efi-next-2026-02-15' of https://source.denx.de/u-boot/custodians/u-boot-efi into next
Pull request efi-next-2026-02-15
CI: https://source.denx.de/u-boot/custodians/u-boot-efi/-/jobs/1380382
UEFI:
* Add MBR support to EFI_PARTITION_INFO_PROTOCOL
* disk: part_dos: Move header to the main include directory
* disk: part_dos: Align dos_partition_t with struct partition
* disk: part_efi: Remove redundant struct partition definition
* disk: part_dos: Document part_get_info_extended() helper function
* disk: part_dos: Refactor to allow retrieving raw MBR partition data
* efi_loader: disk: Extend EFI_PARTITION_INFO_PROTOCOL to support MBR
* efi_selftest: Enhance MBR test for PARTITION_INFO_PROTOCOL
* Prepare for supporting more stores (e.g. SPI-flash) for EFI variables.
* efi_var: Unify read/write access helper function
* efi_loader: Setup default location for UEFI Variables storing
* efi_var_file: refactor to move buffer functions
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/efi_loader/Kconfig | 3 | ||||
| -rw-r--r-- | lib/efi_loader/Makefile | 2 | ||||
| -rw-r--r-- | lib/efi_loader/efi_disk.c | 9 | ||||
| -rw-r--r-- | lib/efi_loader/efi_var_common.c | 42 | ||||
| -rw-r--r-- | lib/efi_loader/efi_var_file.c | 65 | ||||
| -rw-r--r-- | lib/efi_loader/efi_variable.c | 19 | ||||
| -rw-r--r-- | lib/efi_selftest/efi_selftest_block_device.c | 26 |
7 files changed, 94 insertions, 72 deletions
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index 13e44be1d06..579eed65880 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -112,7 +112,8 @@ menu "UEFI Variables" choice prompt "Store for non-volatile UEFI variables" - default EFI_VARIABLE_FILE_STORE + default EFI_VARIABLE_FILE_STORE if FAT_WRITE + default EFI_VARIABLE_NO_STORE help Select where non-volatile UEFI variables shall be stored. diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index f490081f654..ca1775eb03b 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -53,7 +53,7 @@ ifeq ($(CONFIG_EFI_MM_COMM_TEE),y) obj-y += efi_variable_tee.o else obj-y += efi_variable.o -obj-y += efi_var_file.o +obj-$(CONFIG_EFI_VARIABLE_FILE_STORE) += efi_var_file.o obj-$(CONFIG_EFI_VARIABLES_PRESEED) += efi_var_seed.o endif obj-y += efi_watchdog.o diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 130c4db9606..f8a57539ec6 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -475,9 +475,12 @@ static efi_status_t efi_disk_add_dev( #if CONFIG_IS_ENABLED(DOS_PARTITION) case PART_TYPE_DOS: info->type = PARTITION_TYPE_MBR; - - /* TODO: implement support for MBR partition types */ - log_debug("EFI_PARTITION_INFO_PROTOCOL doesn't support MBR\n"); + ret = part_get_mbr(desc, part, &info->info.mbr); + if (ret) { + log_debug("get MBR for part %d failed %ld\n", + part, ret); + goto error; + } break; #endif default: diff --git a/lib/efi_loader/efi_var_common.c b/lib/efi_loader/efi_var_common.c index 4b34a58b4cf..5ea1688dca3 100644 --- a/lib/efi_loader/efi_var_common.c +++ b/lib/efi_loader/efi_var_common.c @@ -41,6 +41,7 @@ static const struct efi_auth_var_name_type name_type[] = { static bool efi_secure_boot; static enum efi_secure_mode efi_secure_mode; +static const efi_guid_t shim_lock_guid = SHIM_LOCK_GUID; /** * efi_efi_get_variable() - retrieve value of a UEFI variable @@ -488,3 +489,44 @@ efi_status_t __maybe_unused efi_var_collect(struct efi_var_file **bufp, loff_t * return EFI_SUCCESS; } + +efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe) +{ + struct efi_var_entry *var, *last_var; + u16 *data; + efi_status_t ret; + + if (buf->reserved || buf->magic != EFI_VAR_FILE_MAGIC || + buf->crc32 != crc32(0, (u8 *)buf->var, + buf->length - sizeof(struct efi_var_file))) { + log_err("Invalid EFI variables file\n"); + return EFI_INVALID_PARAMETER; + } + + last_var = (struct efi_var_entry *)((u8 *)buf + buf->length); + for (var = buf->var; var < last_var; + var = (struct efi_var_entry *)ALIGN((uintptr_t)data + var->length, 8)) { + data = var->name + u16_strlen(var->name) + 1; + + /* + * Secure boot related and volatile variables shall only be + * restored from U-Boot's preseed. + */ + if (!safe && + (efi_auth_var_get_type(var->name, &var->guid) != + EFI_AUTH_VAR_NONE || + !guidcmp(&var->guid, &shim_lock_guid) || + !(var->attr & EFI_VARIABLE_NON_VOLATILE))) + continue; + if (!var->length) + continue; + if (efi_var_mem_find(&var->guid, var->name, NULL)) + continue; + ret = efi_var_mem_ins(var->name, &var->guid, var->attr, + var->length, data, 0, NULL, + var->time); + if (ret != EFI_SUCCESS) + log_err("Failed to set EFI variable %ls\n", var->name); + } + return EFI_SUCCESS; +} diff --git a/lib/efi_loader/efi_var_file.c b/lib/efi_loader/efi_var_file.c index f23a964a418..9cda38f319e 100644 --- a/lib/efi_loader/efi_var_file.c +++ b/lib/efi_loader/efi_var_file.c @@ -14,17 +14,9 @@ #include <mapmem.h> #include <efi_loader.h> #include <efi_variable.h> -#include <u-boot/crc.h> #define PART_STR_LEN 10 -/* GUID used by Shim to store the MOK database */ -#define SHIM_LOCK_GUID \ - EFI_GUID(0x605dab50, 0xe046, 0x4300, \ - 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) - -static const efi_guid_t shim_lock_guid = SHIM_LOCK_GUID; - /** * efi_set_blk_dev_to_system_partition() - select EFI system partition * @@ -51,15 +43,14 @@ static efi_status_t __maybe_unused efi_set_blk_dev_to_system_partition(void) } /** - * efi_var_to_file() - save non-volatile variables as file + * efi_var_to_storage() - save non-volatile variables as file * * File ubootefi.var is created on the EFI system partion. * * Return: status code */ -efi_status_t efi_var_to_file(void) +efi_status_t efi_var_to_storage(void) { -#ifdef CONFIG_EFI_VARIABLE_FILE_STORE efi_status_t ret; struct efi_var_file *buf; loff_t len; @@ -91,56 +82,10 @@ error: out: free(buf); return ret; -#else - return EFI_SUCCESS; -#endif -} - -efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe) -{ - struct efi_var_entry *var, *last_var; - u16 *data; - efi_status_t ret; - - if (buf->reserved || buf->magic != EFI_VAR_FILE_MAGIC || - buf->crc32 != crc32(0, (u8 *)buf->var, - buf->length - sizeof(struct efi_var_file))) { - log_err("Invalid EFI variables file\n"); - return EFI_INVALID_PARAMETER; - } - - last_var = (struct efi_var_entry *)((u8 *)buf + buf->length); - for (var = buf->var; var < last_var; - var = (struct efi_var_entry *) - ALIGN((uintptr_t)data + var->length, 8)) { - - data = var->name + u16_strlen(var->name) + 1; - - /* - * Secure boot related and volatile variables shall only be - * restored from U-Boot's preseed. - */ - if (!safe && - (efi_auth_var_get_type(var->name, &var->guid) != - EFI_AUTH_VAR_NONE || - !guidcmp(&var->guid, &shim_lock_guid) || - !(var->attr & EFI_VARIABLE_NON_VOLATILE))) - continue; - if (!var->length) - continue; - if (efi_var_mem_find(&var->guid, var->name, NULL)) - continue; - ret = efi_var_mem_ins(var->name, &var->guid, var->attr, - var->length, data, 0, NULL, - var->time); - if (ret != EFI_SUCCESS) - log_err("Failed to set EFI variable %ls\n", var->name); - } - return EFI_SUCCESS; } /** - * efi_var_from_file() - read variables from file + * efi_var_from_storage() - read variables from file * * File ubootefi.var is read from the EFI system partitions and the variables * stored in the file are created. @@ -153,9 +98,8 @@ efi_status_t efi_var_restore(struct efi_var_file *buf, bool safe) * * Return: status code */ -efi_status_t efi_var_from_file(void) +efi_status_t efi_var_from_storage(void) { -#ifdef CONFIG_EFI_VARIABLE_FILE_STORE struct efi_var_file *buf; loff_t len; efi_status_t ret; @@ -180,6 +124,5 @@ efi_status_t efi_var_from_file(void) log_err("Invalid EFI variables file\n"); error: free(buf); -#endif return EFI_SUCCESS; } diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index f3533f4def3..8512bc20f11 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -397,11 +397,15 @@ efi_status_t efi_set_variable_int(const u16 *variable_name, ret = EFI_SUCCESS; /* - * Write non-volatile EFI variables to file + * Write non-volatile EFI variables * TODO: check if a value change has occured to avoid superfluous writes */ - if (attributes & EFI_VARIABLE_NON_VOLATILE) - efi_var_to_file(); + if (attributes & EFI_VARIABLE_NON_VOLATILE) { + if (IS_ENABLED(CONFIG_EFI_VARIABLE_NO_STORE)) + return EFI_SUCCESS; + + efi_var_to_storage(); + } return EFI_SUCCESS; } @@ -594,9 +598,12 @@ efi_status_t efi_init_variables(void) if (ret != EFI_SUCCESS) return ret; - ret = efi_var_from_file(); - if (ret != EFI_SUCCESS) - return ret; + if (!IS_ENABLED(CONFIG_EFI_VARIABLE_NO_STORE)) { + ret = efi_var_from_storage(); + if (ret != EFI_SUCCESS) + return ret; + } + if (IS_ENABLED(CONFIG_EFI_VARIABLES_PRESEED)) { ret = efi_var_restore((struct efi_var_file *) __efi_var_file_begin, true); diff --git a/lib/efi_selftest/efi_selftest_block_device.c b/lib/efi_selftest/efi_selftest_block_device.c index f145e58a267..9c4be834eeb 100644 --- a/lib/efi_selftest/efi_selftest_block_device.c +++ b/lib/efi_selftest/efi_selftest_block_device.c @@ -19,6 +19,7 @@ #include "efi_selftest_disk_image.h" #include <asm/cache.h> #include <part_efi.h> +#include <part.h> /* Block size of compressed disk image */ #define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8 @@ -319,6 +320,25 @@ static int execute(void) u64 pos; char block_io_aligned[1 << LB_BLOCK_SIZE] __aligned(1 << LB_BLOCK_SIZE); + /* + * The test disk image is defined in efi_selftest_disk_image.h, + * it contains a single FAT12 partition of 127 sectors size. + */ + static const dos_partition_t mbr_expected = { + .boot_ind = 0x00, + .head = 0x00, + .sector = 0x02, + .cyl = 0x00, + .sys_ind = 0x01, /* FAT12 */ + .end_head = 0x02, + .end_sector = 0x02, + .end_cyl = 0x00, + /* LBA 1 */ + .start_sect = cpu_to_le32(1), + /* Size 127 sectors (0x7f) */ + .nr_sects = cpu_to_le32(127), + }; + /* Connect controller to virtual disk */ ret = boottime->connect_controller(disk_handle, NULL, NULL, 1); if (ret != EFI_SUCCESS) { @@ -405,6 +425,12 @@ static int execute(void) return EFI_ST_FAILURE; } + /* Compare the obtained MBR with the expected one for the test partition */ + if (memcmp(&part_info->info.mbr, &mbr_expected, sizeof(mbr_expected))) { + efi_st_error("MBR partition record mismatch\n"); + return EFI_ST_FAILURE; + } + /* Open the simple file system protocol */ ret = boottime->open_protocol(handle_partition, &guid_simple_file_system_protocol, |
