mirror of
https://github.com/u-boot/u-boot.git
synced 2025-05-08 19:11:53 +00:00
cmd: eficonfig: add support for setting fdt
We already support creating a load option where the device-path field contains the concatenation of the binary device-path and optionally the device path of the initrd which we expose via the EFI_LOAD_FILE2_PROTOCOL. Allow to append another device-path pointing to the device-tree identified by the device-tree GUID. Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> Reviewed-by: Ilias Apalodimas <ilias.apalodimas@linaro.org>
This commit is contained in:
parent
bf03333d09
commit
58bef195f9
3 changed files with 119 additions and 18 deletions
|
@ -61,6 +61,7 @@ struct eficonfig_filepath_info {
|
|||
struct eficonfig_boot_option {
|
||||
struct eficonfig_select_file_info file_info;
|
||||
struct eficonfig_select_file_info initrd_info;
|
||||
struct eficonfig_select_file_info fdt_info;
|
||||
unsigned int boot_index;
|
||||
u16 *description;
|
||||
u16 *optional_data;
|
||||
|
@ -1307,6 +1308,10 @@ static efi_status_t eficonfig_show_boot_option(struct eficonfig_boot_option *bo,
|
|||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
ret = prepare_file_selection_entry(efi_menu, "Fdt File: ", &bo->fdt_info);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
ret = create_boot_option_entry(efi_menu, "Optional Data: ", bo->optional_data,
|
||||
eficonfig_boot_add_optional_data, bo);
|
||||
if (ret != EFI_SUCCESS)
|
||||
|
@ -1387,27 +1392,44 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
|
|||
efi_status_t ret;
|
||||
char *tmp = NULL, *p;
|
||||
struct efi_load_option lo = {0};
|
||||
efi_uintn_t final_dp_size;
|
||||
efi_uintn_t dp_size;
|
||||
struct efi_device_path *dp = NULL;
|
||||
efi_uintn_t size = load_option_size;
|
||||
struct efi_device_path *final_dp = NULL;
|
||||
struct efi_device_path *device_dp = NULL;
|
||||
struct efi_device_path *initrd_dp = NULL;
|
||||
struct efi_device_path *fdt_dp = NULL;
|
||||
struct efi_device_path *initrd_device_dp = NULL;
|
||||
struct efi_device_path *fdt_device_dp = NULL;
|
||||
|
||||
const struct efi_initrd_dp id_dp = {
|
||||
const struct efi_initrd_dp initrd_prefix = {
|
||||
.vendor = {
|
||||
{
|
||||
DEVICE_PATH_TYPE_MEDIA_DEVICE,
|
||||
DEVICE_PATH_SUB_TYPE_VENDOR_PATH,
|
||||
sizeof(id_dp.vendor),
|
||||
sizeof(initrd_prefix.vendor),
|
||||
},
|
||||
EFI_INITRD_MEDIA_GUID,
|
||||
},
|
||||
.end = {
|
||||
DEVICE_PATH_TYPE_END,
|
||||
DEVICE_PATH_SUB_TYPE_END,
|
||||
sizeof(id_dp.end),
|
||||
sizeof(initrd_prefix.end),
|
||||
}
|
||||
};
|
||||
|
||||
const struct efi_initrd_dp fdt_prefix = {
|
||||
.vendor = {
|
||||
{
|
||||
DEVICE_PATH_TYPE_MEDIA_DEVICE,
|
||||
DEVICE_PATH_SUB_TYPE_VENDOR_PATH,
|
||||
sizeof(fdt_prefix.vendor),
|
||||
},
|
||||
EFI_FDT_GUID,
|
||||
},
|
||||
.end = {
|
||||
DEVICE_PATH_TYPE_END,
|
||||
DEVICE_PATH_SUB_TYPE_END,
|
||||
sizeof(initrd_prefix.end),
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1423,6 +1445,12 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
|
|||
goto out;
|
||||
}
|
||||
|
||||
bo->fdt_info.current_path = calloc(1, EFICONFIG_FILE_PATH_BUF_SIZE);
|
||||
if (!bo->fdt_info.current_path) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
|
||||
bo->description = calloc(1, EFICONFIG_DESCRIPTION_MAX * sizeof(u16));
|
||||
if (!bo->description) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
|
@ -1455,13 +1483,20 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
|
|||
if (lo.file_path)
|
||||
fill_file_info(lo.file_path, &bo->file_info, device_dp);
|
||||
|
||||
/* Initrd file path(optional) is placed at second instance. */
|
||||
/* Initrd file path (optional) is placed at second instance. */
|
||||
initrd_dp = efi_dp_from_lo(&lo, &efi_lf2_initrd_guid);
|
||||
if (initrd_dp) {
|
||||
fill_file_info(initrd_dp, &bo->initrd_info, initrd_device_dp);
|
||||
efi_free_pool(initrd_dp);
|
||||
}
|
||||
|
||||
/* Fdt file path (optional) is placed as third instance. */
|
||||
fdt_dp = efi_dp_from_lo(&lo, &efi_guid_fdt);
|
||||
if (fdt_dp) {
|
||||
fill_file_info(fdt_dp, &bo->fdt_info, fdt_device_dp);
|
||||
efi_free_pool(fdt_dp);
|
||||
}
|
||||
|
||||
if (size > 0)
|
||||
memcpy(bo->optional_data, lo.optional_data, size);
|
||||
}
|
||||
|
@ -1483,26 +1518,31 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
|
|||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
initrd_dp = efi_dp_concat((const struct efi_device_path *)&id_dp,
|
||||
initrd_dp = efi_dp_concat((const struct efi_device_path *)&initrd_prefix,
|
||||
dp, 0);
|
||||
efi_free_pool(dp);
|
||||
}
|
||||
|
||||
if (bo->fdt_info.dp_volume) {
|
||||
dp = eficonfig_create_device_path(bo->fdt_info.dp_volume,
|
||||
bo->fdt_info.current_path);
|
||||
if (!dp) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
fdt_dp = efi_dp_concat((const struct efi_device_path *)&fdt_prefix,
|
||||
dp, 0);
|
||||
efi_free_pool(dp);
|
||||
}
|
||||
|
||||
dp = eficonfig_create_device_path(bo->file_info.dp_volume, bo->file_info.current_path);
|
||||
if (!dp) {
|
||||
ret = EFI_OUT_OF_RESOURCES;
|
||||
goto out;
|
||||
}
|
||||
final_dp_size = efi_dp_size(dp) + sizeof(END);
|
||||
if (initrd_dp) {
|
||||
final_dp = efi_dp_concat(dp, initrd_dp, 1);
|
||||
final_dp_size += efi_dp_size(initrd_dp) + sizeof(END);
|
||||
} else {
|
||||
final_dp = efi_dp_dup(dp);
|
||||
}
|
||||
efi_free_pool(dp);
|
||||
|
||||
if (!final_dp)
|
||||
ret = efi_load_option_dp_join(&dp, &dp_size, initrd_dp, fdt_dp);
|
||||
if (ret != EFI_SUCCESS)
|
||||
goto out;
|
||||
|
||||
if (utf16_utf8_strlen(bo->optional_data)) {
|
||||
|
@ -1514,17 +1554,20 @@ static efi_status_t eficonfig_edit_boot_option(u16 *varname, struct eficonfig_bo
|
|||
utf16_utf8_strncpy(&p, bo->optional_data, u16_strlen(bo->optional_data));
|
||||
}
|
||||
|
||||
ret = eficonfig_set_boot_option(varname, final_dp, final_dp_size, bo->description, tmp);
|
||||
ret = eficonfig_set_boot_option(varname, dp, dp_size, bo->description, tmp);
|
||||
out:
|
||||
free(tmp);
|
||||
free(bo->optional_data);
|
||||
free(bo->description);
|
||||
free(bo->file_info.current_path);
|
||||
free(bo->initrd_info.current_path);
|
||||
free(bo->fdt_info.current_path);
|
||||
efi_free_pool(device_dp);
|
||||
efi_free_pool(initrd_device_dp);
|
||||
efi_free_pool(initrd_dp);
|
||||
efi_free_pool(final_dp);
|
||||
efi_free_pool(fdt_device_dp);
|
||||
efi_free_pool(fdt_dp);
|
||||
efi_free_pool(dp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1185,4 +1185,18 @@ efi_status_t efi_disk_get_device_name(const efi_handle_t handle, char *buf, int
|
|||
*/
|
||||
void efi_add_known_memory(void);
|
||||
|
||||
/**
|
||||
* efi_load_option_dp_join() - join device-paths for load option
|
||||
*
|
||||
* @dp: in: binary device-path, out: joined device-path
|
||||
* @dp_size: size of joined device-path
|
||||
* @initrd_dp: initrd device-path or NULL
|
||||
* @fdt_dp: device-tree device-path or NULL
|
||||
* Return: status_code
|
||||
*/
|
||||
efi_status_t efi_load_option_dp_join(struct efi_device_path **dp,
|
||||
size_t *dp_size,
|
||||
struct efi_device_path *initrd_dp,
|
||||
struct efi_device_path *fdt_dp);
|
||||
|
||||
#endif /* _EFI_LOADER_H */
|
||||
|
|
|
@ -99,6 +99,50 @@ err:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_load_option_dp_join() - join device-paths for load option
|
||||
*
|
||||
* @dp: in: binary device-path, out: joined device-path
|
||||
* @dp_size: size of joined device-path
|
||||
* @initrd_dp: initrd device-path or NULL
|
||||
* @fdt_dp: device-tree device-path or NULL
|
||||
* Return: status_code
|
||||
*/
|
||||
efi_status_t efi_load_option_dp_join(struct efi_device_path **dp,
|
||||
size_t *dp_size,
|
||||
struct efi_device_path *initrd_dp,
|
||||
struct efi_device_path *fdt_dp)
|
||||
{
|
||||
if (!dp)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
*dp_size = efi_dp_size(*dp);
|
||||
|
||||
if (initrd_dp) {
|
||||
struct efi_device_path *tmp_dp = *dp;
|
||||
|
||||
*dp = efi_dp_concat(tmp_dp, initrd_dp, *dp_size);
|
||||
efi_free_pool(tmp_dp);
|
||||
if (!*dp)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
*dp_size += efi_dp_size(initrd_dp) + sizeof(END);
|
||||
}
|
||||
|
||||
if (fdt_dp) {
|
||||
struct efi_device_path *tmp_dp = *dp;
|
||||
|
||||
*dp = efi_dp_concat(tmp_dp, fdt_dp, *dp_size);
|
||||
efi_free_pool(tmp_dp);
|
||||
if (!dp)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
*dp_size += efi_dp_size(fdt_dp) + sizeof(END);
|
||||
}
|
||||
|
||||
*dp_size += sizeof(END);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
const struct guid_to_hash_map {
|
||||
efi_guid_t guid;
|
||||
const char algo[32];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue