mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-20 11:55:03 +00:00
efi_loader: bootmgr: add load option helper functions
In this patch, helper functions for an load option variable (BootXXXX) are added: * efi_deserialize_load_option(): parse a string into load_option data (renamed from parse_load_option and exported) * efi_serialize_load_option(): convert load_option data into a string Those functions will be used to implement efishell command. Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
2419b161cc
commit
1a82b3413c
2 changed files with 83 additions and 33 deletions
|
@ -518,6 +518,29 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor,
|
||||||
u32 attributes, efi_uintn_t data_size,
|
u32 attributes, efi_uintn_t data_size,
|
||||||
void *data);
|
void *data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* See section 3.1.3 in the v2.7 UEFI spec for more details on
|
||||||
|
* the layout of EFI_LOAD_OPTION. In short it is:
|
||||||
|
*
|
||||||
|
* typedef struct _EFI_LOAD_OPTION {
|
||||||
|
* UINT32 Attributes;
|
||||||
|
* UINT16 FilePathListLength;
|
||||||
|
* // CHAR16 Description[]; <-- variable length, NULL terminated
|
||||||
|
* // EFI_DEVICE_PATH_PROTOCOL FilePathList[];
|
||||||
|
* <-- FilePathListLength bytes
|
||||||
|
* // UINT8 OptionalData[];
|
||||||
|
* } EFI_LOAD_OPTION;
|
||||||
|
*/
|
||||||
|
struct efi_load_option {
|
||||||
|
u32 attributes;
|
||||||
|
u16 file_path_length;
|
||||||
|
u16 *label;
|
||||||
|
struct efi_device_path *file_path;
|
||||||
|
u8 *optional_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data);
|
||||||
|
unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data);
|
||||||
void *efi_bootmgr_load(struct efi_device_path **device_path,
|
void *efi_bootmgr_load(struct efi_device_path **device_path,
|
||||||
struct efi_device_path **file_path);
|
struct efi_device_path **file_path);
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <charset.h>
|
#include <charset.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <efi_loader.h>
|
#include <efi_loader.h>
|
||||||
|
#include <asm/unaligned.h>
|
||||||
|
|
||||||
static const struct efi_boot_services *bs;
|
static const struct efi_boot_services *bs;
|
||||||
static const struct efi_runtime_services *rs;
|
static const struct efi_runtime_services *rs;
|
||||||
|
@ -30,42 +31,68 @@ static const struct efi_runtime_services *rs;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* Parse serialized data and transform it into efi_load_option structure */
|
||||||
* See section 3.1.3 in the v2.7 UEFI spec for more details on
|
void efi_deserialize_load_option(struct efi_load_option *lo, u8 *data)
|
||||||
* the layout of EFI_LOAD_OPTION. In short it is:
|
|
||||||
*
|
|
||||||
* typedef struct _EFI_LOAD_OPTION {
|
|
||||||
* UINT32 Attributes;
|
|
||||||
* UINT16 FilePathListLength;
|
|
||||||
* // CHAR16 Description[]; <-- variable length, NULL terminated
|
|
||||||
* // EFI_DEVICE_PATH_PROTOCOL FilePathList[]; <-- FilePathListLength bytes
|
|
||||||
* // UINT8 OptionalData[];
|
|
||||||
* } EFI_LOAD_OPTION;
|
|
||||||
*/
|
|
||||||
struct load_option {
|
|
||||||
u32 attributes;
|
|
||||||
u16 file_path_length;
|
|
||||||
u16 *label;
|
|
||||||
struct efi_device_path *file_path;
|
|
||||||
u8 *optional_data;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* parse an EFI_LOAD_OPTION, as described above */
|
|
||||||
static void parse_load_option(struct load_option *lo, void *ptr)
|
|
||||||
{
|
{
|
||||||
lo->attributes = *(u32 *)ptr;
|
lo->attributes = get_unaligned_le32(data);
|
||||||
ptr += sizeof(u32);
|
data += sizeof(u32);
|
||||||
|
|
||||||
lo->file_path_length = *(u16 *)ptr;
|
lo->file_path_length = get_unaligned_le16(data);
|
||||||
ptr += sizeof(u16);
|
data += sizeof(u16);
|
||||||
|
|
||||||
lo->label = ptr;
|
/* FIXME */
|
||||||
ptr += (u16_strlen(lo->label) + 1) * 2;
|
lo->label = (u16 *)data;
|
||||||
|
data += (u16_strlen(lo->label) + 1) * sizeof(u16);
|
||||||
|
|
||||||
lo->file_path = ptr;
|
/* FIXME */
|
||||||
ptr += lo->file_path_length;
|
lo->file_path = (struct efi_device_path *)data;
|
||||||
|
data += lo->file_path_length;
|
||||||
|
|
||||||
lo->optional_data = ptr;
|
lo->optional_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serialize efi_load_option structure into byte stream for BootXXXX.
|
||||||
|
* Return a size of allocated data.
|
||||||
|
*/
|
||||||
|
unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data)
|
||||||
|
{
|
||||||
|
unsigned long label_len, option_len;
|
||||||
|
unsigned long size;
|
||||||
|
u8 *p;
|
||||||
|
|
||||||
|
label_len = (u16_strlen(lo->label) + 1) * sizeof(u16);
|
||||||
|
option_len = strlen((char *)lo->optional_data);
|
||||||
|
|
||||||
|
/* total size */
|
||||||
|
size = sizeof(lo->attributes);
|
||||||
|
size += sizeof(lo->file_path_length);
|
||||||
|
size += label_len;
|
||||||
|
size += lo->file_path_length;
|
||||||
|
size += option_len + 1;
|
||||||
|
p = malloc(size);
|
||||||
|
if (!p)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* copy data */
|
||||||
|
*data = p;
|
||||||
|
memcpy(p, &lo->attributes, sizeof(lo->attributes));
|
||||||
|
p += sizeof(lo->attributes);
|
||||||
|
|
||||||
|
memcpy(p, &lo->file_path_length, sizeof(lo->file_path_length));
|
||||||
|
p += sizeof(lo->file_path_length);
|
||||||
|
|
||||||
|
memcpy(p, lo->label, label_len);
|
||||||
|
p += label_len;
|
||||||
|
|
||||||
|
memcpy(p, lo->file_path, lo->file_path_length);
|
||||||
|
p += lo->file_path_length;
|
||||||
|
|
||||||
|
memcpy(p, lo->optional_data, option_len);
|
||||||
|
p += option_len;
|
||||||
|
*(char *)p = '\0';
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free() the result */
|
/* free() the result */
|
||||||
|
@ -100,7 +127,7 @@ static void *get_var(u16 *name, const efi_guid_t *vendor,
|
||||||
static void *try_load_entry(uint16_t n, struct efi_device_path **device_path,
|
static void *try_load_entry(uint16_t n, struct efi_device_path **device_path,
|
||||||
struct efi_device_path **file_path)
|
struct efi_device_path **file_path)
|
||||||
{
|
{
|
||||||
struct load_option lo;
|
struct efi_load_option lo;
|
||||||
u16 varname[] = L"Boot0000";
|
u16 varname[] = L"Boot0000";
|
||||||
u16 hexmap[] = L"0123456789ABCDEF";
|
u16 hexmap[] = L"0123456789ABCDEF";
|
||||||
void *load_option, *image = NULL;
|
void *load_option, *image = NULL;
|
||||||
|
@ -115,7 +142,7 @@ static void *try_load_entry(uint16_t n, struct efi_device_path **device_path,
|
||||||
if (!load_option)
|
if (!load_option)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
parse_load_option(&lo, load_option);
|
efi_deserialize_load_option(&lo, load_option);
|
||||||
|
|
||||||
if (lo.attributes & LOAD_OPTION_ACTIVE) {
|
if (lo.attributes & LOAD_OPTION_ACTIVE) {
|
||||||
efi_status_t ret;
|
efi_status_t ret;
|
||||||
|
|
Loading…
Add table
Reference in a new issue