mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
tools: mkeficapsule: support generating dynamic GUIDs
Add support for generating GUIDs that match those generated internally by U-Boot for capsule update fw_images when using dynamic UUIDs. Dynamic UUIDs in U-Boot work by taking a namespace UUID and hashing it with the board compatible and fw_image name. This feature just provides a way to determine the UUIDs for a particular board without having to actually boot U-Boot on it. Acked-by: Ilias Apalodimas <ilias.apalodimas@linaro.org> Signed-off-by: Caleb Connolly <caleb.connolly@linaro.org>
This commit is contained in:
committed by
Heinrich Schuchardt
parent
f102e0d08d
commit
7558385e48
@@ -10,6 +10,9 @@ mkeficapsule \- Generate EFI capsule file for U-Boot
|
||||
.B mkeficapsule
|
||||
.RI [ options ] " " [ image-blob ] " " capsule-file
|
||||
|
||||
.B mkeficapsule
|
||||
.RI guidgen " " [ GUID ] " " DTB " " IMAGE_NAME...
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
The
|
||||
.B mkeficapsule
|
||||
@@ -42,6 +45,10 @@ multiple binary blobs in a single capsule file.
|
||||
This type of image file can be generated by
|
||||
.BR mkimage .
|
||||
|
||||
mkeficapsule can also be used to simulate the dynamic GUID generation used to
|
||||
identify firmware images in capsule updates by providing the namespace guid, dtb
|
||||
for the board, and a list of firmware images.
|
||||
|
||||
.SH "OPTIONS"
|
||||
|
||||
.TP
|
||||
@@ -117,6 +124,22 @@ at every firmware update.
|
||||
.B "-d\fR,\fB --dump_sig"
|
||||
Dump signature data into *.p7 file
|
||||
|
||||
.SH "GUIDGEN OPTIONS"
|
||||
|
||||
.TP
|
||||
.B "[GUID]"
|
||||
The namespace/salt GUID, by default this is EFI_CAPSULE_NAMESPACE_GUID.
|
||||
The format is:
|
||||
xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
|
||||
.TP
|
||||
.B DTB
|
||||
The device tree blob file for the board.
|
||||
|
||||
.TP
|
||||
.B IMAGE_NAME...
|
||||
The names of the firmware images to generate GUIDs for.
|
||||
|
||||
.PP
|
||||
.SH FILES
|
||||
.TP
|
||||
|
||||
@@ -22,10 +22,14 @@
|
||||
#include <gnutls/abstract.h>
|
||||
|
||||
#include <version.h>
|
||||
#include <libfdt.h>
|
||||
#include <u-boot/uuid.h>
|
||||
|
||||
#include "eficapsule.h"
|
||||
|
||||
// Matches CONFIG_EFI_CAPSULE_NAMESPACE_GUID
|
||||
#define DEFAULT_NAMESPACE_GUID "8c9f137e-91dc-427b-b2d6-b420faebaf2a"
|
||||
|
||||
static const char *tool_name = "mkeficapsule";
|
||||
|
||||
efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
|
||||
@@ -56,9 +60,20 @@ static struct option options[] = {
|
||||
{NULL, 0, NULL, 0},
|
||||
};
|
||||
|
||||
static void print_usage(void)
|
||||
static void print_usage_guidgen(void)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [options] <image blob> <output file>\n"
|
||||
fprintf(stderr, "%s guidgen [GUID] DTB IMAGE_NAME...\n"
|
||||
"Options:\n"
|
||||
|
||||
"\tGUID Namespace GUID (default: %s)\n"
|
||||
"\tDTB Device Tree Blob\n"
|
||||
"\tIMAGE_NAME... One or more names of fw_images to generate GUIDs for\n",
|
||||
tool_name, DEFAULT_NAMESPACE_GUID);
|
||||
}
|
||||
|
||||
static void print_usage_mkeficapsule(void)
|
||||
{
|
||||
fprintf(stderr, "Usage:\n\n%s [options] <image blob> <output file>\n"
|
||||
"Options:\n"
|
||||
|
||||
"\t-g, --guid <guid string> guid for image blob type\n"
|
||||
@@ -74,8 +89,9 @@ static void print_usage(void)
|
||||
"\t-o, --capoemflag Capsule OEM Flag, an integer between 0x0000 and 0xffff\n"
|
||||
"\t-D, --dump-capsule dump the contents of the capsule headers\n"
|
||||
"\t-V, --version show version number\n"
|
||||
"\t-h, --help print a help message\n",
|
||||
"\t-h, --help print a help message\n\n",
|
||||
tool_name);
|
||||
print_usage_guidgen();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -820,6 +836,129 @@ static void dump_capsule_contents(char *capsule_file)
|
||||
}
|
||||
}
|
||||
|
||||
static struct fdt_header *load_dtb(const char *path)
|
||||
{
|
||||
struct fdt_header *dtb;
|
||||
ssize_t dtb_size;
|
||||
FILE *f;
|
||||
|
||||
/* Open and parse DTB */
|
||||
f = fopen(path, "r");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Cannot open %s\n", path);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fseek(f, 0, SEEK_END)) {
|
||||
fprintf(stderr, "Cannot seek to the end of %s: %s\n",
|
||||
path, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dtb_size = ftell(f);
|
||||
if (dtb_size < 0) {
|
||||
fprintf(stderr, "Cannot ftell %s: %s\n",
|
||||
path, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
dtb = malloc(dtb_size);
|
||||
if (!dtb) {
|
||||
fprintf(stderr, "Can't allocated %ld\n", dtb_size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fread(dtb, dtb_size, 1, f) != 1) {
|
||||
fprintf(stderr, "Can't read %ld bytes from %s\n",
|
||||
dtb_size, path);
|
||||
free(dtb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
return dtb;
|
||||
}
|
||||
|
||||
#define MAX_IMAGE_NAME_LEN 128
|
||||
static int genguid(int argc, char **argv)
|
||||
{
|
||||
int idx = 2, ret;
|
||||
unsigned char namespace[16];
|
||||
struct efi_guid image_type_id;
|
||||
const char *dtb_path;
|
||||
struct fdt_header *dtb;
|
||||
const char *compatible;
|
||||
int compatlen, namelen;
|
||||
uint16_t fw_image[MAX_IMAGE_NAME_LEN];
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: ");
|
||||
print_usage_guidgen();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uuid_str_to_bin(argv[1], namespace, UUID_STR_FORMAT_GUID)) {
|
||||
uuid_str_to_bin(DEFAULT_NAMESPACE_GUID, namespace, UUID_STR_FORMAT_GUID);
|
||||
dtb_path = argv[1];
|
||||
} else {
|
||||
dtb_path = argv[2];
|
||||
idx = 3;
|
||||
}
|
||||
|
||||
if (idx == argc) {
|
||||
fprintf(stderr, "Usage: ");
|
||||
print_usage_guidgen();
|
||||
return -1;
|
||||
}
|
||||
|
||||
dtb = load_dtb(dtb_path);
|
||||
if (!dtb)
|
||||
return -1;
|
||||
|
||||
ret = fdt_check_header(dtb);
|
||||
if (ret) {
|
||||
fprintf(stderr, "Invalid DTB header: %d\n", ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
compatible = fdt_getprop(dtb, 0, "compatible", &compatlen);
|
||||
if (!compatible) {
|
||||
fprintf(stderr, "No compatible string found in DTB\n");
|
||||
return -1;
|
||||
}
|
||||
if (strnlen(compatible, compatlen) >= compatlen) {
|
||||
fprintf(stderr, "Compatible string not null-terminated\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Generating GUIDs for %s with namespace %s:\n",
|
||||
compatible, DEFAULT_NAMESPACE_GUID);
|
||||
for (; idx < argc; idx++) {
|
||||
memset(fw_image, 0, sizeof(fw_image));
|
||||
namelen = strlen(argv[idx]);
|
||||
if (namelen > MAX_IMAGE_NAME_LEN) {
|
||||
fprintf(stderr, "Image name too long: %s\n", argv[idx]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < namelen; i++)
|
||||
fw_image[i] = (uint16_t)argv[idx][i];
|
||||
|
||||
gen_v5_guid((struct uuid *)&namespace, &image_type_id,
|
||||
compatible, strlen(compatible),
|
||||
fw_image, namelen * sizeof(uint16_t),
|
||||
NULL);
|
||||
|
||||
printf("%s: ", argv[idx]);
|
||||
print_guid(&image_type_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* main - main entry function of mkeficapsule
|
||||
* @argc: Number of arguments
|
||||
@@ -844,6 +983,13 @@ int main(int argc, char **argv)
|
||||
int c, idx;
|
||||
struct fmp_payload_header_params fmp_ph_params = { 0 };
|
||||
|
||||
/* Generate dynamic GUIDs */
|
||||
if (argc > 1 && !strcmp(argv[1], "guidgen")) {
|
||||
if (genguid(argc - 1, argv + 1))
|
||||
exit(EXIT_FAILURE);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
guid = NULL;
|
||||
index = 0;
|
||||
instance = 0;
|
||||
@@ -935,7 +1081,7 @@ int main(int argc, char **argv)
|
||||
printf("mkeficapsule version %s\n", PLAIN_VERSION);
|
||||
exit(EXIT_SUCCESS);
|
||||
default:
|
||||
print_usage();
|
||||
print_usage_mkeficapsule();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@@ -958,7 +1104,7 @@ int main(int argc, char **argv)
|
||||
((argc != optind + 1) ||
|
||||
((capsule_type == CAPSULE_ACCEPT) && !guid) ||
|
||||
((capsule_type == CAPSULE_REVERT) && guid)))) {
|
||||
print_usage();
|
||||
print_usage_mkeficapsule();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user