mirror of
https://github.com/u-boot/u-boot.git
synced 2025-04-16 01:44:34 +00:00
tools: mkfwumdata: add support for metadata version 2
Add support for generating the FWU metadata version 2. The tool now requires the version to be provided as a command-line option. Make corresponding changes to the tool's manpage. Signed-off-by: Sughosh Ganu <sughosh.ganu@linaro.org> Tested-by: Michal Simek <michal.simek@amd.com>
This commit is contained in:
parent
7cfe0d8a48
commit
df42d68496
2 changed files with 127 additions and 30 deletions
|
@ -6,6 +6,7 @@ mkfwumdata \- create FWU metadata image
|
|||
.
|
||||
.SH SYNOPSIS
|
||||
.SY mkfwumdata
|
||||
.OP \-v version
|
||||
.OP \-a activeidx
|
||||
.OP \-p previousidx
|
||||
.OP \-g
|
||||
|
@ -28,6 +29,12 @@ creates metadata info to be used with FWU.
|
|||
Print usage information and exit.
|
||||
.
|
||||
.TP
|
||||
.B \-v
|
||||
Set
|
||||
.IR version
|
||||
as the metadata version to generate. Valid values 1 or 2.
|
||||
.
|
||||
.TP
|
||||
.B \-a
|
||||
Set
|
||||
.IR activeidx
|
||||
|
@ -81,7 +88,7 @@ Create a metadata image with 2 banks and 1 image/bank, BankAct=0, BankPrev=1:
|
|||
.EX
|
||||
.in +4
|
||||
$ \c
|
||||
.B mkfwumdata \-a 0 \-p 1 \-b 2 \-i 1 \\\\\&
|
||||
.B mkfwumdata \-v 2 \-a 0 \-p 1 \-b 2 \-i 1 \\\\\&
|
||||
.in +6
|
||||
.B 17e86d77-41f9-4fd7-87ec-a55df9842de5,\\\\\&
|
||||
.B 10c36d7d-ca52-b843-b7b9-f9d6c501d108,\\\\\&
|
||||
|
|
|
@ -10,28 +10,35 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <u-boot/crc.h>
|
||||
#include <unistd.h>
|
||||
#include <generated/autoconf.h>
|
||||
#include <u-boot/crc.h>
|
||||
#include <uuid/uuid.h>
|
||||
|
||||
/* This will dynamically allocate the fwu_mdata */
|
||||
#define CONFIG_FWU_NUM_BANKS 0
|
||||
#define CONFIG_FWU_NUM_IMAGES_PER_BANK 0
|
||||
|
||||
/* Since we can not include fwu.h, redefine version here. */
|
||||
#define FWU_MDATA_VERSION 1
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef int16_t s16;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
#undef CONFIG_FWU_NUM_BANKS
|
||||
#undef CONFIG_FWU_NUM_IMAGES_PER_BANK
|
||||
|
||||
/* This will dynamically allocate the fwu_mdata */
|
||||
#define CONFIG_FWU_NUM_BANKS 0
|
||||
#define CONFIG_FWU_NUM_IMAGES_PER_BANK 0
|
||||
|
||||
/* version 2 supports maximum of 4 banks */
|
||||
#define MAX_BANKS_V2 4
|
||||
|
||||
#define BANK_INVALID (u8)0xFF
|
||||
#define BANK_ACCEPTED (u8)0xFC
|
||||
|
||||
#include <fwu_mdata.h>
|
||||
|
||||
/* TODO: Endianness conversion may be required for some arch. */
|
||||
|
||||
static const char *opts_short = "b:i:a:p:gh";
|
||||
static const char *opts_short = "b:i:a:p:v:gh";
|
||||
|
||||
static struct option options[] = {
|
||||
{"banks", required_argument, NULL, 'b'},
|
||||
|
@ -39,6 +46,7 @@ static struct option options[] = {
|
|||
{"guid", required_argument, NULL, 'g'},
|
||||
{"active-bank", required_argument, NULL, 'a'},
|
||||
{"previous-bank", required_argument, NULL, 'p'},
|
||||
{"version", required_argument, NULL, 'v'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{NULL, 0, NULL, 0},
|
||||
};
|
||||
|
@ -49,6 +57,7 @@ static void print_usage(void)
|
|||
fprintf(stderr, "Options:\n"
|
||||
"\t-i, --images <num> Number of images (mandatory)\n"
|
||||
"\t-b, --banks <num> Number of banks (mandatory)\n"
|
||||
"\t-v, --version Metadata version (mandatory)\n"
|
||||
"\t-a, --active-bank <num> Active bank (default=0)\n"
|
||||
"\t-p, --previous-bank <num> Previous active bank (default=active_bank - 1)\n"
|
||||
"\t-g, --guid Use GUID instead of UUID\n"
|
||||
|
@ -70,13 +79,26 @@ struct fwu_mdata_object {
|
|||
size_t images;
|
||||
size_t banks;
|
||||
size_t size;
|
||||
u8 version;
|
||||
struct fwu_mdata *mdata;
|
||||
};
|
||||
|
||||
static int previous_bank, active_bank;
|
||||
static bool __use_guid;
|
||||
|
||||
static struct fwu_mdata_object *fwu_alloc_mdata(size_t images, size_t banks)
|
||||
static bool supported_mdata_version(unsigned long version)
|
||||
{
|
||||
switch (version) {
|
||||
case 1:
|
||||
case 2:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static struct fwu_mdata_object *fwu_alloc_mdata(size_t images, size_t banks,
|
||||
u8 version)
|
||||
{
|
||||
struct fwu_mdata_object *mobj;
|
||||
|
||||
|
@ -84,11 +106,20 @@ static struct fwu_mdata_object *fwu_alloc_mdata(size_t images, size_t banks)
|
|||
if (!mobj)
|
||||
return NULL;
|
||||
|
||||
if (version == 1) {
|
||||
mobj->size = sizeof(struct fwu_mdata) +
|
||||
(sizeof(struct fwu_image_entry) +
|
||||
sizeof(struct fwu_image_bank_info) * banks) * images;
|
||||
} else {
|
||||
mobj->size = sizeof(struct fwu_mdata) +
|
||||
sizeof(struct fwu_fw_store_desc) +
|
||||
(sizeof(struct fwu_image_entry) +
|
||||
sizeof(struct fwu_image_bank_info) * banks) * images;
|
||||
}
|
||||
|
||||
mobj->images = images;
|
||||
mobj->banks = banks;
|
||||
mobj->version = version;
|
||||
|
||||
mobj->mdata = calloc(1, mobj->size);
|
||||
if (!mobj->mdata) {
|
||||
|
@ -104,9 +135,18 @@ fwu_get_image(struct fwu_mdata_object *mobj, size_t idx)
|
|||
{
|
||||
size_t offset;
|
||||
|
||||
if (mobj->version == 1) {
|
||||
offset = sizeof(struct fwu_mdata) +
|
||||
(sizeof(struct fwu_image_entry) +
|
||||
sizeof(struct fwu_image_bank_info) * mobj->banks) * idx;
|
||||
sizeof(struct fwu_image_bank_info) * mobj->banks) *
|
||||
idx;
|
||||
} else {
|
||||
offset = sizeof(struct fwu_mdata) +
|
||||
sizeof(struct fwu_fw_store_desc) +
|
||||
(sizeof(struct fwu_image_entry) +
|
||||
sizeof(struct fwu_image_bank_info) * mobj->banks) *
|
||||
idx;
|
||||
}
|
||||
|
||||
return (struct fwu_image_entry *)((char *)mobj->mdata + offset);
|
||||
}
|
||||
|
@ -116,11 +156,20 @@ fwu_get_bank(struct fwu_mdata_object *mobj, size_t img_idx, size_t bnk_idx)
|
|||
{
|
||||
size_t offset;
|
||||
|
||||
if (mobj->version == 1) {
|
||||
offset = sizeof(struct fwu_mdata) +
|
||||
(sizeof(struct fwu_image_entry) +
|
||||
sizeof(struct fwu_image_bank_info) * mobj->banks) * img_idx +
|
||||
sizeof(struct fwu_image_entry) +
|
||||
sizeof(struct fwu_image_bank_info) * mobj->banks) *
|
||||
img_idx + sizeof(struct fwu_image_entry) +
|
||||
sizeof(struct fwu_image_bank_info) * bnk_idx;
|
||||
} else {
|
||||
offset = sizeof(struct fwu_mdata) +
|
||||
sizeof(struct fwu_fw_store_desc) +
|
||||
(sizeof(struct fwu_image_entry) +
|
||||
sizeof(struct fwu_image_bank_info) * mobj->banks) *
|
||||
img_idx + sizeof(struct fwu_image_entry) +
|
||||
sizeof(struct fwu_image_bank_info) * bnk_idx;
|
||||
}
|
||||
|
||||
return (struct fwu_image_bank_info *)((char *)mobj->mdata + offset);
|
||||
}
|
||||
|
@ -188,7 +237,7 @@ fwu_parse_fill_image_uuid(struct fwu_mdata_object *mobj,
|
|||
return -EINVAL;
|
||||
|
||||
if (strcmp(uuid, "0") &&
|
||||
uuid_guid_parse(uuid, (unsigned char *)&image->location_uuid) < 0)
|
||||
uuid_guid_parse(uuid, (unsigned char *)&image->location_guid) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Image type UUID */
|
||||
|
@ -196,7 +245,7 @@ fwu_parse_fill_image_uuid(struct fwu_mdata_object *mobj,
|
|||
if (!uuid)
|
||||
return -EINVAL;
|
||||
|
||||
if (uuid_guid_parse(uuid, (unsigned char *)&image->image_type_uuid) < 0)
|
||||
if (uuid_guid_parse(uuid, (unsigned char *)&image->image_type_guid) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Fill bank image-UUID */
|
||||
|
@ -210,22 +259,52 @@ fwu_parse_fill_image_uuid(struct fwu_mdata_object *mobj,
|
|||
return -EINVAL;
|
||||
|
||||
if (strcmp(uuid, "0") &&
|
||||
uuid_guid_parse(uuid, (unsigned char *)&bank->image_uuid) < 0)
|
||||
uuid_guid_parse(uuid, (unsigned char *)&bank->image_guid) < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_FWU_MDATA_V1)
|
||||
static void fwu_fill_version_specific_mdata(struct fwu_mdata_object *mobj)
|
||||
{
|
||||
}
|
||||
#else
|
||||
static void fwu_fill_version_specific_mdata(struct fwu_mdata_object *mobj)
|
||||
{
|
||||
int i;
|
||||
struct fwu_fw_store_desc *fw_desc;
|
||||
struct fwu_mdata *mdata = mobj->mdata;
|
||||
|
||||
mdata->metadata_size = mobj->size;
|
||||
mdata->desc_offset = sizeof(struct fwu_mdata);
|
||||
|
||||
for (i = 0; i < MAX_BANKS_V2; i++)
|
||||
mdata->bank_state[i] = i < mobj->banks ?
|
||||
BANK_ACCEPTED : BANK_INVALID;
|
||||
|
||||
fw_desc = (struct fwu_fw_store_desc *)((u8 *)mdata + sizeof(*mdata));
|
||||
fw_desc->num_banks = mobj->banks;
|
||||
fw_desc->num_images = mobj->images;
|
||||
fw_desc->img_entry_size = sizeof(struct fwu_image_entry) +
|
||||
(sizeof(struct fwu_image_bank_info) * mobj->banks);
|
||||
fw_desc->bank_info_entry_size =
|
||||
sizeof(struct fwu_image_bank_info);
|
||||
}
|
||||
#endif /* CONFIG_FWU_MDATA_V1 */
|
||||
|
||||
/* Caller must ensure that @uuids[] has @mobj->images entries. */
|
||||
static int fwu_parse_fill_uuids(struct fwu_mdata_object *mobj, char *uuids[])
|
||||
{
|
||||
struct fwu_mdata *mdata = mobj->mdata;
|
||||
int i, ret;
|
||||
|
||||
mdata->version = FWU_MDATA_VERSION;
|
||||
mdata->version = mobj->version;
|
||||
mdata->active_index = active_bank;
|
||||
mdata->previous_active_index = previous_bank;
|
||||
|
||||
fwu_fill_version_specific_mdata(mobj);
|
||||
|
||||
for (i = 0; i < mobj->images; i++) {
|
||||
ret = fwu_parse_fill_image_uuid(mobj, i, uuids[i]);
|
||||
if (ret < 0)
|
||||
|
@ -239,13 +318,14 @@ static int fwu_parse_fill_uuids(struct fwu_mdata_object *mobj, char *uuids[])
|
|||
}
|
||||
|
||||
static int
|
||||
fwu_make_mdata(size_t images, size_t banks, char *uuids[], char *output)
|
||||
fwu_make_mdata(size_t images, size_t banks, u8 version, char *uuids[],
|
||||
char *output)
|
||||
{
|
||||
struct fwu_mdata_object *mobj;
|
||||
FILE *file;
|
||||
int ret;
|
||||
|
||||
mobj = fwu_alloc_mdata(images, banks);
|
||||
mobj = fwu_alloc_mdata(images, banks, version);
|
||||
if (!mobj)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -276,7 +356,7 @@ done_make:
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned long banks = 0, images = 0;
|
||||
unsigned long banks = 0, images = 0, version = 0;
|
||||
int c, ret;
|
||||
|
||||
/* Explicitly initialize defaults */
|
||||
|
@ -305,6 +385,9 @@ int main(int argc, char *argv[])
|
|||
case 'a':
|
||||
active_bank = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'v':
|
||||
version = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
}
|
||||
} while (c != -1);
|
||||
|
||||
|
@ -313,6 +396,12 @@ int main(int argc, char *argv[])
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!version || !supported_mdata_version(version)) {
|
||||
fprintf(stderr, "Error: Version value can only be either 1 or 2, not %ld.\n",
|
||||
version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* This command takes UUIDs * images and output file. */
|
||||
if (optind + images + 1 != argc) {
|
||||
fprintf(stderr, "Error: UUID list or output file is not specified or too much.\n");
|
||||
|
@ -325,7 +414,8 @@ int main(int argc, char *argv[])
|
|||
previous_bank = active_bank > 0 ? active_bank - 1 : banks - 1;
|
||||
}
|
||||
|
||||
ret = fwu_make_mdata(images, banks, argv + optind, argv[argc - 1]);
|
||||
ret = fwu_make_mdata(images, banks, (u8)version, argv + optind,
|
||||
argv[argc - 1]);
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "Error: Failed to parse and write image: %s\n",
|
||||
strerror(-ret));
|
||||
|
|
Loading…
Add table
Reference in a new issue