Message ID | 20210115180250.154660-2-xypron.glpk@gmx.de |
---|---|
State | Superseded, archived |
Delegated to: | Heinrich Schuchardt |
Headers | show |
Series | efi_loader: make the UEFI boot manager configurable | expand |
On Fri, Jan 15, 2021 at 07:02:49PM +0100, Heinrich Schuchardt wrote: > Move all load options related functions to a new module. So that they can > be compiled independently. > > Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> > --- > lib/efi_loader/efi_load_options.c | 151 ++++++++++++++++++++++++++++++ > 1 file changed, 151 insertions(+) > create mode 100644 lib/efi_loader/efi_load_options.c > > diff --git a/lib/efi_loader/efi_load_options.c b/lib/efi_loader/efi_load_options.c > new file mode 100644 > index 0000000000..9f0e25b6e9 > --- /dev/null > +++ b/lib/efi_loader/efi_load_options.c > @@ -0,0 +1,151 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * EFI boot manager > + * > + * Copyright (c) 2017 Rob Clark Some part of the code in this file was originally written by me. -Takahiro Akashi > + */ > + > +#define LOG_CATEGORY LOGC_EFI > + > +#include <common.h> > +#include <charset.h> > +#include <log.h> > +#include <malloc.h> > +#include <efi_loader.h> > +//#include <efi_variable.h> > +#include <asm/unaligned.h> > + > +/** > + * efi_set_load_options() - set the load options of a loaded image > + * > + * @handle: the image handle > + * @load_options_size: size of load options > + * @load_options: pointer to load options > + * Return: status code > + */ > +efi_status_t efi_set_load_options(efi_handle_t handle, > + efi_uintn_t load_options_size, > + void *load_options) > +{ > + struct efi_loaded_image *loaded_image_info; > + efi_status_t ret; > + > + ret = EFI_CALL(systab.boottime->open_protocol( > + handle, > + &efi_guid_loaded_image, > + (void **)&loaded_image_info, > + efi_root, NULL, > + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)); > + if (ret != EFI_SUCCESS) > + return EFI_INVALID_PARAMETER; > + > + loaded_image_info->load_options = load_options; > + loaded_image_info->load_options_size = load_options_size; > + > + return EFI_CALL(systab.boottime->close_protocol(handle, > + &efi_guid_loaded_image, > + efi_root, NULL)); > +} > + > +/** > + * efi_deserialize_load_option() - parse serialized data > + * > + * Parse serialized data describing a load option and transform it to the > + * efi_load_option structure. > + * > + * @lo: pointer to target > + * @data: serialized data > + * @size: size of the load option, on return size of the optional data > + * Return: status code > + */ > +efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data, > + efi_uintn_t *size) > +{ > + efi_uintn_t len; > + > + len = sizeof(u32); > + if (*size < len + 2 * sizeof(u16)) > + return EFI_INVALID_PARAMETER; > + lo->attributes = get_unaligned_le32(data); > + data += len; > + *size -= len; > + > + len = sizeof(u16); > + lo->file_path_length = get_unaligned_le16(data); > + data += len; > + *size -= len; > + > + lo->label = (u16 *)data; > + len = u16_strnlen(lo->label, *size / sizeof(u16) - 1); > + if (lo->label[len]) > + return EFI_INVALID_PARAMETER; > + len = (len + 1) * sizeof(u16); > + if (*size < len) > + return EFI_INVALID_PARAMETER; > + data += len; > + *size -= len; > + > + len = lo->file_path_length; > + if (*size < len) > + return EFI_INVALID_PARAMETER; > + lo->file_path = (struct efi_device_path *)data; > + if (efi_dp_check_length(lo->file_path, len) < 0) > + return EFI_INVALID_PARAMETER; > + data += len; > + *size -= len; > + > + lo->optional_data = data; > + > + return EFI_SUCCESS; > +} > + > +/** > + * efi_serialize_load_option() - serialize load option > + * > + * Serialize efi_load_option structure into byte stream for BootXXXX. > + * > + * @data: buffer for serialized data > + * @lo: load option > + * Return: size of allocated buffer > + */ > +unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) > +{ > + unsigned long label_len; > + unsigned long size; > + u8 *p; > + > + label_len = (u16_strlen(lo->label) + 1) * sizeof(u16); > + > + /* total size */ > + size = sizeof(lo->attributes); > + size += sizeof(lo->file_path_length); > + size += label_len; > + size += lo->file_path_length; > + if (lo->optional_data) > + size += (utf8_utf16_strlen((const char *)lo->optional_data) > + + 1) * sizeof(u16); > + 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; > + > + if (lo->optional_data) { > + utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data); > + p += sizeof(u16); /* size of trailing \0 */ > + } > + return size; > +} > + > -- > 2.29.2 >
On 1/18/21 3:17 AM, AKASHI Takahiro wrote: > On Fri, Jan 15, 2021 at 07:02:49PM +0100, Heinrich Schuchardt wrote: >> Move all load options related functions to a new module. So that they can >> be compiled independently. >> >> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> >> --- >> lib/efi_loader/efi_load_options.c | 151 ++++++++++++++++++++++++++++++ >> 1 file changed, 151 insertions(+) >> create mode 100644 lib/efi_loader/efi_load_options.c >> >> diff --git a/lib/efi_loader/efi_load_options.c b/lib/efi_loader/efi_load_options.c >> new file mode 100644 >> index 0000000000..9f0e25b6e9 >> --- /dev/null >> +++ b/lib/efi_loader/efi_load_options.c >> @@ -0,0 +1,151 @@ >> +// SPDX-License-Identifier: GPL-2.0+ >> +/* >> + * EFI boot manager >> + * >> + * Copyright (c) 2017 Rob Clark > > Some part of the code in this file was originally written by me. I will add your name. Other projects simply say don't put names into the text because their will be further contributors anyways. Best regards Heinrich > > -Takahiro Akashi > >> + */ >> + >> +#define LOG_CATEGORY LOGC_EFI >> + >> +#include <common.h> >> +#include <charset.h> >> +#include <log.h> >> +#include <malloc.h> >> +#include <efi_loader.h> >> +//#include <efi_variable.h> >> +#include <asm/unaligned.h> >> + >> +/** >> + * efi_set_load_options() - set the load options of a loaded image >> + * >> + * @handle: the image handle >> + * @load_options_size: size of load options >> + * @load_options: pointer to load options >> + * Return: status code >> + */ >> +efi_status_t efi_set_load_options(efi_handle_t handle, >> + efi_uintn_t load_options_size, >> + void *load_options) >> +{ >> + struct efi_loaded_image *loaded_image_info; >> + efi_status_t ret; >> + >> + ret = EFI_CALL(systab.boottime->open_protocol( >> + handle, >> + &efi_guid_loaded_image, >> + (void **)&loaded_image_info, >> + efi_root, NULL, >> + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)); >> + if (ret != EFI_SUCCESS) >> + return EFI_INVALID_PARAMETER; >> + >> + loaded_image_info->load_options = load_options; >> + loaded_image_info->load_options_size = load_options_size; >> + >> + return EFI_CALL(systab.boottime->close_protocol(handle, >> + &efi_guid_loaded_image, >> + efi_root, NULL)); >> +} >> + >> +/** >> + * efi_deserialize_load_option() - parse serialized data >> + * >> + * Parse serialized data describing a load option and transform it to the >> + * efi_load_option structure. >> + * >> + * @lo: pointer to target >> + * @data: serialized data >> + * @size: size of the load option, on return size of the optional data >> + * Return: status code >> + */ >> +efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data, >> + efi_uintn_t *size) >> +{ >> + efi_uintn_t len; >> + >> + len = sizeof(u32); >> + if (*size < len + 2 * sizeof(u16)) >> + return EFI_INVALID_PARAMETER; >> + lo->attributes = get_unaligned_le32(data); >> + data += len; >> + *size -= len; >> + >> + len = sizeof(u16); >> + lo->file_path_length = get_unaligned_le16(data); >> + data += len; >> + *size -= len; >> + >> + lo->label = (u16 *)data; >> + len = u16_strnlen(lo->label, *size / sizeof(u16) - 1); >> + if (lo->label[len]) >> + return EFI_INVALID_PARAMETER; >> + len = (len + 1) * sizeof(u16); >> + if (*size < len) >> + return EFI_INVALID_PARAMETER; >> + data += len; >> + *size -= len; >> + >> + len = lo->file_path_length; >> + if (*size < len) >> + return EFI_INVALID_PARAMETER; >> + lo->file_path = (struct efi_device_path *)data; >> + if (efi_dp_check_length(lo->file_path, len) < 0) >> + return EFI_INVALID_PARAMETER; >> + data += len; >> + *size -= len; >> + >> + lo->optional_data = data; >> + >> + return EFI_SUCCESS; >> +} >> + >> +/** >> + * efi_serialize_load_option() - serialize load option >> + * >> + * Serialize efi_load_option structure into byte stream for BootXXXX. >> + * >> + * @data: buffer for serialized data >> + * @lo: load option >> + * Return: size of allocated buffer >> + */ >> +unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) >> +{ >> + unsigned long label_len; >> + unsigned long size; >> + u8 *p; >> + >> + label_len = (u16_strlen(lo->label) + 1) * sizeof(u16); >> + >> + /* total size */ >> + size = sizeof(lo->attributes); >> + size += sizeof(lo->file_path_length); >> + size += label_len; >> + size += lo->file_path_length; >> + if (lo->optional_data) >> + size += (utf8_utf16_strlen((const char *)lo->optional_data) >> + + 1) * sizeof(u16); >> + 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; >> + >> + if (lo->optional_data) { >> + utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data); >> + p += sizeof(u16); /* size of trailing \0 */ >> + } >> + return size; >> +} >> + >> -- >> 2.29.2 >>
Hi Heinrich, Overall the patch and idea seem fine. Would it make sense to name the file differently? Something similar to what I did on my initrd patches, i.e efi_helper.c, so we can start adding helper functions that have a wider usage? Thanks /Ilias On Fri, Jan 15, 2021 at 07:02:49PM +0100, Heinrich Schuchardt wrote: > Move all load options related functions to a new module. So that they can > be compiled independently. > > Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> > --- > lib/efi_loader/efi_load_options.c | 151 ++++++++++++++++++++++++++++++ > 1 file changed, 151 insertions(+) > create mode 100644 lib/efi_loader/efi_load_options.c > > diff --git a/lib/efi_loader/efi_load_options.c b/lib/efi_loader/efi_load_options.c > new file mode 100644 > index 0000000000..9f0e25b6e9 > --- /dev/null > +++ b/lib/efi_loader/efi_load_options.c > @@ -0,0 +1,151 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * EFI boot manager > + * > + * Copyright (c) 2017 Rob Clark > + */ > + > +#define LOG_CATEGORY LOGC_EFI > + > +#include <common.h> > +#include <charset.h> > +#include <log.h> > +#include <malloc.h> > +#include <efi_loader.h> > +//#include <efi_variable.h> > +#include <asm/unaligned.h> > + > +/** > + * efi_set_load_options() - set the load options of a loaded image > + * > + * @handle: the image handle > + * @load_options_size: size of load options > + * @load_options: pointer to load options > + * Return: status code > + */ > +efi_status_t efi_set_load_options(efi_handle_t handle, > + efi_uintn_t load_options_size, > + void *load_options) > +{ > + struct efi_loaded_image *loaded_image_info; > + efi_status_t ret; > + > + ret = EFI_CALL(systab.boottime->open_protocol( > + handle, > + &efi_guid_loaded_image, > + (void **)&loaded_image_info, > + efi_root, NULL, > + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)); > + if (ret != EFI_SUCCESS) > + return EFI_INVALID_PARAMETER; > + > + loaded_image_info->load_options = load_options; > + loaded_image_info->load_options_size = load_options_size; > + > + return EFI_CALL(systab.boottime->close_protocol(handle, > + &efi_guid_loaded_image, > + efi_root, NULL)); > +} > + > +/** > + * efi_deserialize_load_option() - parse serialized data > + * > + * Parse serialized data describing a load option and transform it to the > + * efi_load_option structure. > + * > + * @lo: pointer to target > + * @data: serialized data > + * @size: size of the load option, on return size of the optional data > + * Return: status code > + */ > +efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data, > + efi_uintn_t *size) > +{ > + efi_uintn_t len; > + > + len = sizeof(u32); > + if (*size < len + 2 * sizeof(u16)) > + return EFI_INVALID_PARAMETER; > + lo->attributes = get_unaligned_le32(data); > + data += len; > + *size -= len; > + > + len = sizeof(u16); > + lo->file_path_length = get_unaligned_le16(data); > + data += len; > + *size -= len; > + > + lo->label = (u16 *)data; > + len = u16_strnlen(lo->label, *size / sizeof(u16) - 1); > + if (lo->label[len]) > + return EFI_INVALID_PARAMETER; > + len = (len + 1) * sizeof(u16); > + if (*size < len) > + return EFI_INVALID_PARAMETER; > + data += len; > + *size -= len; > + > + len = lo->file_path_length; > + if (*size < len) > + return EFI_INVALID_PARAMETER; > + lo->file_path = (struct efi_device_path *)data; > + if (efi_dp_check_length(lo->file_path, len) < 0) > + return EFI_INVALID_PARAMETER; > + data += len; > + *size -= len; > + > + lo->optional_data = data; > + > + return EFI_SUCCESS; > +} > + > +/** > + * efi_serialize_load_option() - serialize load option > + * > + * Serialize efi_load_option structure into byte stream for BootXXXX. > + * > + * @data: buffer for serialized data > + * @lo: load option > + * Return: size of allocated buffer > + */ > +unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) > +{ > + unsigned long label_len; > + unsigned long size; > + u8 *p; > + > + label_len = (u16_strlen(lo->label) + 1) * sizeof(u16); > + > + /* total size */ > + size = sizeof(lo->attributes); > + size += sizeof(lo->file_path_length); > + size += label_len; > + size += lo->file_path_length; > + if (lo->optional_data) > + size += (utf8_utf16_strlen((const char *)lo->optional_data) > + + 1) * sizeof(u16); > + 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; > + > + if (lo->optional_data) { > + utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data); > + p += sizeof(u16); /* size of trailing \0 */ > + } > + return size; > +} > + > -- > 2.29.2 >
On 19.01.21 08:42, Ilias Apalodimas wrote: > Hi Heinrich, > > Overall the patch and idea seem fine. > Would it make sense to name the file differently? > Something similar to what I did on my initrd patches, i.e efi_helper.c, so we > can start adding helper functions that have a wider usage? efi_helper.c as a name does not convey which functions to find there. Concerning your initrd patch series: efi_get_var() would fit into efi_var_common.c. efi_dp_instance_by_idx() would fit into efi_device_path.c. create_boot_var_indexed() seems to duplicate efi_create_indexed_name() which is in efi_string.c. Leaves us only with efi_get_fp_from_boot() which is only relevant for the boot manager. Best regards Heinrich > > > Thanks > /Ilias > > On Fri, Jan 15, 2021 at 07:02:49PM +0100, Heinrich Schuchardt wrote: >> Move all load options related functions to a new module. So that they can >> be compiled independently. >> >> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> >> --- >> lib/efi_loader/efi_load_options.c | 151 ++++++++++++++++++++++++++++++ >> 1 file changed, 151 insertions(+) >> create mode 100644 lib/efi_loader/efi_load_options.c
diff --git a/lib/efi_loader/efi_load_options.c b/lib/efi_loader/efi_load_options.c new file mode 100644 index 0000000000..9f0e25b6e9 --- /dev/null +++ b/lib/efi_loader/efi_load_options.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * EFI boot manager + * + * Copyright (c) 2017 Rob Clark + */ + +#define LOG_CATEGORY LOGC_EFI + +#include <common.h> +#include <charset.h> +#include <log.h> +#include <malloc.h> +#include <efi_loader.h> +//#include <efi_variable.h> +#include <asm/unaligned.h> + +/** + * efi_set_load_options() - set the load options of a loaded image + * + * @handle: the image handle + * @load_options_size: size of load options + * @load_options: pointer to load options + * Return: status code + */ +efi_status_t efi_set_load_options(efi_handle_t handle, + efi_uintn_t load_options_size, + void *load_options) +{ + struct efi_loaded_image *loaded_image_info; + efi_status_t ret; + + ret = EFI_CALL(systab.boottime->open_protocol( + handle, + &efi_guid_loaded_image, + (void **)&loaded_image_info, + efi_root, NULL, + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL)); + if (ret != EFI_SUCCESS) + return EFI_INVALID_PARAMETER; + + loaded_image_info->load_options = load_options; + loaded_image_info->load_options_size = load_options_size; + + return EFI_CALL(systab.boottime->close_protocol(handle, + &efi_guid_loaded_image, + efi_root, NULL)); +} + +/** + * efi_deserialize_load_option() - parse serialized data + * + * Parse serialized data describing a load option and transform it to the + * efi_load_option structure. + * + * @lo: pointer to target + * @data: serialized data + * @size: size of the load option, on return size of the optional data + * Return: status code + */ +efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data, + efi_uintn_t *size) +{ + efi_uintn_t len; + + len = sizeof(u32); + if (*size < len + 2 * sizeof(u16)) + return EFI_INVALID_PARAMETER; + lo->attributes = get_unaligned_le32(data); + data += len; + *size -= len; + + len = sizeof(u16); + lo->file_path_length = get_unaligned_le16(data); + data += len; + *size -= len; + + lo->label = (u16 *)data; + len = u16_strnlen(lo->label, *size / sizeof(u16) - 1); + if (lo->label[len]) + return EFI_INVALID_PARAMETER; + len = (len + 1) * sizeof(u16); + if (*size < len) + return EFI_INVALID_PARAMETER; + data += len; + *size -= len; + + len = lo->file_path_length; + if (*size < len) + return EFI_INVALID_PARAMETER; + lo->file_path = (struct efi_device_path *)data; + if (efi_dp_check_length(lo->file_path, len) < 0) + return EFI_INVALID_PARAMETER; + data += len; + *size -= len; + + lo->optional_data = data; + + return EFI_SUCCESS; +} + +/** + * efi_serialize_load_option() - serialize load option + * + * Serialize efi_load_option structure into byte stream for BootXXXX. + * + * @data: buffer for serialized data + * @lo: load option + * Return: size of allocated buffer + */ +unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data) +{ + unsigned long label_len; + unsigned long size; + u8 *p; + + label_len = (u16_strlen(lo->label) + 1) * sizeof(u16); + + /* total size */ + size = sizeof(lo->attributes); + size += sizeof(lo->file_path_length); + size += label_len; + size += lo->file_path_length; + if (lo->optional_data) + size += (utf8_utf16_strlen((const char *)lo->optional_data) + + 1) * sizeof(u16); + 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; + + if (lo->optional_data) { + utf8_utf16_strcpy((u16 **)&p, (const char *)lo->optional_data); + p += sizeof(u16); /* size of trailing \0 */ + } + return size; +} +
Move all load options related functions to a new module. So that they can be compiled independently. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> --- lib/efi_loader/efi_load_options.c | 151 ++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 lib/efi_loader/efi_load_options.c -- 2.29.2