/* * Get size of a device path. * * This function implements the GetDevicePathSize service of the device path * utilities protocol. The device path length includes the end of path tag * which may be an instance end. * * See the Unified Extensible Firmware Interface (UEFI) specification * for details. * * @device_path device path * @return size in bytes */ static efi_uintn_t EFIAPI get_device_path_size( const struct efi_device_path *device_path) { efi_uintn_t sz = 0; EFI_ENTRY("%pD", device_path); /* size includes the END node: */ if (device_path) sz = efi_dp_size(device_path) + sizeof(struct efi_device_path); return EFI_EXIT(sz); }
/** * do_efi_boot_add() - set UEFI load option * * @cmdtp: Command table * @flag: Command flag * @argc: Number of arguments * @argv: Argument array * Return: CMD_RET_SUCCESS on success, * CMD_RET_USAGE or CMD_RET_RET_FAILURE on failure * * Implement efidebug "boot add" sub-command. * Create or change UEFI load option. * - boot add <id> <label> <interface> <devnum>[:<part>] <file> <options> */ static int do_efi_boot_add(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int id; char *endp; char var_name[9]; u16 var_name16[9], *p; efi_guid_t guid; size_t label_len, label_len16; u16 *label; struct efi_device_path *device_path = NULL, *file_path = NULL; struct efi_load_option lo; void *data = NULL; efi_uintn_t size; int ret; if (argc < 6 || argc > 7) return CMD_RET_USAGE; id = (int)simple_strtoul(argv[1], &endp, 16); if (*endp != '\0' || id > 0xffff) return CMD_RET_USAGE; sprintf(var_name, "Boot%04X", id); p = var_name16; utf8_utf16_strncpy(&p, var_name, 9); guid = efi_global_variable_guid; /* attributes */ lo.attributes = LOAD_OPTION_ACTIVE; /* always ACTIVE */ /* label */ label_len = strlen(argv[2]); label_len16 = utf8_utf16_strnlen(argv[2], label_len); label = malloc((label_len16 + 1) * sizeof(u16)); if (!label) return CMD_RET_FAILURE; lo.label = label; /* label will be changed below */ utf8_utf16_strncpy(&label, argv[2], label_len); /* file path */ ret = efi_dp_from_name(argv[3], argv[4], argv[5], &device_path, &file_path); if (ret != EFI_SUCCESS) { printf("Cannot create device path for \"%s %s\"\n", argv[3], argv[4]); ret = CMD_RET_FAILURE; goto out; } lo.file_path = file_path; lo.file_path_length = efi_dp_size(file_path) + sizeof(struct efi_device_path); /* for END */ /* optional data */ lo.optional_data = (u8 *)(argc == 6 ? "" : argv[6]); size = efi_serialize_load_option(&lo, (u8 **)&data); if (!size) { ret = CMD_RET_FAILURE; goto out; } ret = EFI_CALL(RT->set_variable(var_name16, &guid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, size, data)); ret = (ret == EFI_SUCCESS ? CMD_RET_SUCCESS : CMD_RET_FAILURE); out: free(data); efi_free_pool(device_path); efi_free_pool(file_path); free(lo.label); return ret; }