From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: u-boot@lists.denx.de
Subject: [RFC 13/14] tools: add mkeficapsule command for UEFI capsule update test
Date: Wed, 18 Mar 2020 10:32:38 +0900 [thread overview]
Message-ID: <20200318013237.GR13880@linaro.org> (raw)
In-Reply-To: <2befee04-ac36-dc3e-b969-46c94bab87c7@gmx.de>
On Tue, Mar 17, 2020 at 08:58:55AM +0100, Heinrich Schuchardt wrote:
> On 3/17/20 3:12 AM, AKASHI Takahiro wrote:
> > This is a utility mainly for test purpose.
> > mkeficapsule -f: create a FIT image firmware capsule
>
> The UEFI spec defines a capsule format and how to invoke it by placing
> the file in the right directory before reboot. Why do we need a FIT
> image firmware capsule?
??? I don't get your point.
A capsule is just a wrapper that can hold any kind (or format) of
binary data. In fact, an associated capsule driver should know
how the data should correctly be handled on U-Boot.
So if you provide your own driver (more specifically, "firmware
management protocol" for firmware update), you can encapsulate
any firmware in your proprietary format.
In this RFC, I provide a *sample* driver for a single FIT image
in patch#9.
Thanks,
-Takahiro Akashi
> Best regards
>
> Heinrich
>
> > mkeficapsule -v: create a specific test case capsule for variables
> >
> > Having said that, you will be able to customize the code to fit
> > your specific requirements for your platform.
> >
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > ---
> > tools/Makefile | 3 +
> > tools/mkeficapsule.c | 501 +++++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 504 insertions(+)
> > create mode 100644 tools/mkeficapsule.c
> >
> > diff --git a/tools/Makefile b/tools/Makefile
> > index 99be724b82a5..fe07f8952f49 100644
> > --- a/tools/Makefile
> > +++ b/tools/Makefile
> > @@ -222,6 +222,9 @@ hostprogs-$(CONFIG_MIPS) += mips-relocs
> > hostprogs-$(CONFIG_ASN1_COMPILER) += asn1_compiler
> > HOSTCFLAGS_asn1_compiler.o = -idirafter $(srctree)/include
> >
> > +# TODO: only build this for capsule pytest
> > +hostprogs-$(CONFIG_EFI_CAPSULE_UPDATE) += mkeficapsule
> > +
> > # We build some files with extra pedantic flags to try to minimize things
> > # that won't build on some weird host compiler -- though there are lots of
> > # exceptions for files that aren't complaint.
> > diff --git a/tools/mkeficapsule.c b/tools/mkeficapsule.c
> > new file mode 100644
> > index 000000000000..732a54811df9
> > --- /dev/null
> > +++ b/tools/mkeficapsule.c
> > @@ -0,0 +1,501 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright 2018 Linaro Limited
> > + * Author: AKASHI Takahiro
> > + */
> > +
> > +#include <malloc.h>
> > +#include <stdio.h>
> > +#include <string.h>
> > +#include <sys/stat.h>
> > +#include <sys/types.h>
> > +/*
> > + * TODO: use libefi/libgnuefi headers
> > + */
> > +
> > +typedef u_int8_t u8;
> > +typedef u_int16_t u16;
> > +typedef u_int32_t u32;
> > +typedef u_int64_t u64;
> > +
> > +/* include/efi.h */
> > +typedef struct {
> > + u8 b[16];
> > +} efi_guid_t;
> > +
> > +#define EFI_GUID(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7) \
> > + {{ (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, \
> > + ((a) >> 24) & 0xff, \
> > + (b) & 0xff, ((b) >> 8) & 0xff, \
> > + (c) & 0xff, ((c) >> 8) & 0xff, \
> > + (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) } }
> > +
> > +#define EFI_VARIABLE_NON_VOLATILE 0x0000000000000001
> > +#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
> > +#define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004
> > +
> > +/* include/efi_api.h */
> > +#define EFI_GLOBAL_VARIABLE_GUID \
> > + EFI_GUID(0x8be4df61, 0x93ca, 0x11d2, 0xaa, 0x0d, \
> > + 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c)
> > +
> > +#define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000
> > +#define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000
> > +#define CAPSULE_FLAGS_INITIATE_RESET 0x00040000
> > +
> > +#define EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID \
> > + EFI_GUID(0xae13ff2d, 0x9ad4, 0x4e25, 0x9a, 0xc8, \
> > + 0x6d, 0x80, 0xb3, 0xb2, 0x21, 0x47)
> > +
> > +#define EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID \
> > + EFI_GUID(0x6dcbd5ed, 0xe82d, 0x4c44, 0xbd, 0xa1, \
> > + 0x71, 0x94, 0x19, 0x9a, 0xd9, 0x2a)
> > +
> > +#define EFI_VARIABLE_STORAGE_GUID \
> > + EFI_GUID(0x1a3fb419, 0x2171, 0x458d, 0xb8, 0xb4, \
> > + 0xbe, 0xa3, 0x0c, 0x9f, 0x6b, 0xab)
> > +
> > +struct efi_capsule_header {
> > + efi_guid_t capsule_guid;
> > + u32 header_size;
> > + u32 flags;
> > + u32 capsule_image_size;
> > +} __attribute__((packed));
> > +
> > +struct efi_capsule_block_descriptor {
> > + u64 length;
> > + union {
> > + u64 data_block;
> > + u64 continuation_ptr;
> > + };
> > +} __attribute__((packed));
> > +
> > +struct efi_firmware_management_capsule_header {
> > + u32 version;
> > + u16 embedded_driver_count;
> > + u16 payload_item_count;
> > + u64 item_offset_list[];
> > +} __attribute__((packed));
> > +
> > +struct efi_firmware_management_capsule_image_header {
> > + u32 version;
> > + efi_guid_t update_image_type_id;
> > + u8 update_image_index;
> > + u8 reserved[3];
> > + u32 update_image_size;
> > + u32 update_vendor_code_size;
> > + u64 update_hardware_instance;
> > +} __attribute__((packed));
> > +
> > +struct efi_ebbr_variable {
> > + u16 variable_name[64];
> > + efi_guid_t vendor_guid;
> > + u32 attributes;
> > + u32 data_size;
> > + u8 data[];
> > +};
> > +
> > +struct efi_ebbr_variable_bundle {
> > + struct efi_capsule_header header;
> > + u8 reserved[0];
> > + struct efi_ebbr_variable variables[];
> > +} __attribute__((packed));
> > +
> > +efi_guid_t efi_guid_fm_capsule = EFI_FIRMWARE_MANAGEMENT_CAPSULE_ID_GUID;
> > +efi_guid_t efi_guid_image_type_uboot_fit =
> > + EFI_FIRMWARE_IMAGE_TYPE_UBOOT_FIT_GUID;
> > +efi_guid_t efi_guid_variable_storage = EFI_VARIABLE_STORAGE_GUID;
> > +efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
> > +
> > +/* generated by efi boot add 3 TEST scsi 0:0 /EFI/Images/hello.efi "" */
> > +char boot_var3[] = "0100000052005400450053005400000001041400b9731de684a3cc4aaeab82e828f3628b0302080000000000040432005c005c004500460049005c0049006d0061006700650073005c00680065006c006c006f002e0065006600690000007fff040000";
> > +u16 boot_order[] = {
> > + 0x0003,
> > + 0x0002,
> > +};
> > +
> > +/* efi_variable.c */
> > +static int hex(int ch)
> > +{
> > + if (ch >= 'a' && ch <= 'f')
> > + return ch - 'a' + 10;
> > + if (ch >= '0' && ch <= '9')
> > + return ch - '0';
> > + if (ch >= 'A' && ch <= 'F')
> > + return ch - 'A' + 10;
> > + return -1;
> > +}
> > +
> > +static int hex2mem(u8 *mem, const char *hexstr, int size)
> > +{
> > + int nibble;
> > + int i;
> > +
> > + for (i = 0; i < size; i++) {
> > + if (*hexstr == '\0')
> > + break;
> > +
> > + nibble = hex(*hexstr);
> > + if (nibble < 0)
> > + return -1;
> > +
> > + *mem = nibble;
> > + hexstr++;
> > +
> > + nibble = hex(*hexstr);
> > + if (nibble < 0)
> > + return -1;
> > +
> > + *mem = (*mem << 4) | nibble;
> > + hexstr++;
> > + mem++;
> > + }
> > +
> > + return i;
> > +}
> > +
> > +void wcharcpy(u16 *dst, wchar_t *src, size_t n)
> > +{
> > + int i;
> > +
> > + for (i = 0; i < n; i++)
> > + *dst++ = *src++;
> > +}
> > +
> > +static int create_fwbin(char *bin, char *path)
> > +{
> > + struct efi_capsule_header header;
> > + struct efi_firmware_management_capsule_header capsule;
> > + struct efi_firmware_management_capsule_image_header image;
> > + FILE *f, *g;
> > + struct stat bin_stat;
> > + u8 *data;
> > + size_t size;
> > +
> > + g = fopen(bin, "r");
> > + if (!g) {
> > + printf("cannot open %s\n", bin);
> > + return -1;
> > + }
> > + if (stat(bin, &bin_stat) < 0) {
> > + printf("cannot determine the size of %s\n", bin);
> > + goto err_1;
> > + }
> > + data = malloc(bin_stat.st_size);
> > + if (!data) {
> > + printf("cannot allocate memory: %lx\n", bin_stat.st_size);
> > + goto err_1;
> > + }
> > + f = fopen(path, "w");
> > + if (!f) {
> > + printf("cannot open %s\n", path);
> > + goto err_2;
> > + }
> > + header.capsule_guid = efi_guid_fm_capsule;
> > + header.header_size = sizeof(header);
> > + header.flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET; /* TODO */
> > + header.capsule_image_size = sizeof(header)
> > + + sizeof(capsule) + sizeof(u64)
> > + + sizeof(image)
> > + + bin_stat.st_size;
> > +
> > + size = fwrite(&header, 1, sizeof(header), f);
> > + if (size < sizeof(header)) {
> > + printf("write failed (%lx)\n", size);
> > + goto err_3;
> > + }
> > +
> > + capsule.version = 0x00000001;
> > + capsule.embedded_driver_count = 0;
> > + capsule.payload_item_count = 1;
> > + capsule.item_offset_list[0] = sizeof(capsule) + sizeof(u64);
> > + size = fwrite(&capsule, 1, sizeof(capsule) + sizeof(u64), f);
> > + if (size < (sizeof(capsule) + sizeof(u64))) {
> > + printf("write failed (%lx)\n", size);
> > + goto err_3;
> > + }
> > +
> > + image.version = 0x00000002;
> > + image.update_image_type_id = efi_guid_image_type_uboot_fit;
> > + image.update_image_index = 1;
> > + image.update_image_size = bin_stat.st_size;
> > + image.update_vendor_code_size = 0; /* none */
> > + image.update_hardware_instance = 1;
> > +
> > + size = fwrite(&image, 1, sizeof(image), f);
> > + if (size < sizeof(image)) {
> > + printf("write failed (%lx)\n", size);
> > + goto err_3;
> > + }
> > + size = fread(data, 1, bin_stat.st_size, g);
> > + if (size < bin_stat.st_size) {
> > + printf("read failed (%lx)\n", size);
> > + goto err_3;
> > + }
> > + size = fwrite(data, 1, bin_stat.st_size, f);
> > + if (size < bin_stat.st_size) {
> > + printf("write failed (%lx)\n", size);
> > + goto err_3;
> > + }
> > +
> > + fclose(f);
> > + fclose(g);
> > + free(data);
> > +
> > + return 0;
> > +
> > +err_3:
> > + fclose(f);
> > +err_2:
> > + free(data);
> > +err_1:
> > + fclose(g);
> > +
> > + return -1;
> > +}
> > +
> > +static int create_test1(char *path)
> > +{
> > + FILE *f;
> > + size_t size;
> > + struct efi_capsule_header header;
> > + struct efi_ebbr_variable variable;
> > + u8 *data;
> > + size_t data_size;
> > +
> > + f = fopen(path, "w");
> > + if (!f) {
> > + printf("cannot open %s\n", path);
> > + return -1;
> > + }
> > + header.capsule_guid = efi_guid_variable_storage;
> > + header.header_size = sizeof(header);
> > + header.flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET; /* TODO */
> > + header.capsule_image_size = sizeof(header);
> > +
> > + size = fwrite(&header, 1, sizeof(header), f);
> > + if (size < sizeof(header)) {
> > + printf("write failed (%lx)\n", size);
> > + return -1;
> > + }
> > +
> > + /* add a new variable */
> > + data_size = sizeof(boot_var3) / 2;
> > + data = malloc(data_size);
> > + if (!data) {
> > + printf("memory allocation failed\n");
> > + return -1;
> > + }
> > + hex2mem(data, boot_var3, data_size);
> > + wcharcpy(variable.variable_name, L"Boot0003", 9);
> > + variable.vendor_guid = efi_global_variable_guid;
> > + variable.attributes = (EFI_VARIABLE_NON_VOLATILE |
> > + EFI_VARIABLE_BOOTSERVICE_ACCESS |
> > + EFI_VARIABLE_RUNTIME_ACCESS);
> > + variable.data_size = data_size;
> > + header.capsule_image_size += sizeof(variable) + variable.data_size;
> > +
> > + size = fwrite(&variable, 1, sizeof(variable), f);
> > + if (size < sizeof(variable)) {
> > + printf("write failed (%lx)\n", size);
> > + return -1;
> > + }
> > + size = fwrite(data, 1, data_size, f);
> > + if (size < data_size) {
> > + printf("write failed (%lx)\n", size);
> > + return -1;
> > + }
> > +
> > + /* update capsule image size */
> > + rewind(f);
> > + size = fwrite(&header, 1, sizeof(header), f);
> > + if (size < sizeof(header)) {
> > + printf("write failed (%lx)\n", size);
> > + return -1;
> > + }
> > +
> > + fclose(f);
> > +
> > + return 0;
> > +}
> > +
> > +static int create_test2(char *path)
> > +{
> > + FILE *f;
> > + size_t size;
> > + struct efi_capsule_header header;
> > + struct efi_ebbr_variable variable;
> > +
> > + f = fopen(path, "w");
> > + if (!f) {
> > + printf("cannot open %s\n", path);
> > + return -1;
> > + }
> > + header.capsule_guid = efi_guid_variable_storage;
> > + header.header_size = sizeof(header);
> > + header.flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET; /* TODO */
> > + header.capsule_image_size = sizeof(header);
> > +
> > + size = fwrite(&header, 1, sizeof(header), f);
> > + if (size < sizeof(header)) {
> > + printf("write failed (%lx)\n", size);
> > + return -1;
> > + }
> > +
> > + /* modify an existing variable */
> > + wcharcpy(variable.variable_name, L"BootOrder", 10);
> > + variable.vendor_guid = efi_global_variable_guid;
> > + variable.attributes = (EFI_VARIABLE_NON_VOLATILE |
> > + EFI_VARIABLE_BOOTSERVICE_ACCESS |
> > + EFI_VARIABLE_RUNTIME_ACCESS);
> > + variable.data_size = sizeof(boot_order);
> > + header.capsule_image_size += sizeof(variable) + variable.data_size;
> > +
> > + size = fwrite(&variable, 1, sizeof(variable), f);
> > + if (size < sizeof(variable)) {
> > + printf("write failed (%lx)\n", size);
> > + return -1;
> > + }
> > + size = fwrite(boot_order, 1, sizeof(boot_order), f);
> > + if (size < sizeof(boot_order)) {
> > + printf("write failed (%lx)\n", size);
> > + return -1;
> > + }
> > +
> > + /* delete an existing variable */
> > + wcharcpy(variable.variable_name, L"Boot0001", 9);
> > + variable.vendor_guid = efi_global_variable_guid;
> > + variable.attributes = (EFI_VARIABLE_NON_VOLATILE |
> > + EFI_VARIABLE_BOOTSERVICE_ACCESS |
> > + EFI_VARIABLE_RUNTIME_ACCESS);
> > + variable.data_size = 0;
> > + header.capsule_image_size += sizeof(variable) + variable.data_size;
> > +
> > + size = fwrite(&variable, 1, sizeof(variable), f);
> > + if (size < sizeof(variable)) {
> > + printf("write failed (%lx)\n", size);
> > + return -1;
> > + }
> > +
> > + /* update capsule image size */
> > + rewind(f);
> > + size = fwrite(&header, 1, sizeof(header), f);
> > + if (size < sizeof(header)) {
> > + printf("write failed (%lx)\n", size);
> > + return -1;
> > + }
> > +
> > + fclose(f);
> > +
> > + return 0;
> > +}
> > +
> > +static int create_test3(char *path)
> > +{
> > + FILE *f;
> > + size_t size;
> > + struct efi_capsule_header header;
> > + struct efi_ebbr_variable variable;
> > +
> > + f = fopen(path, "w");
> > + if (!f) {
> > + printf("cannot open %s\n", path);
> > + return -1;
> > + }
> > + header.capsule_guid = efi_guid_variable_storage;
> > + header.header_size = sizeof(header);
> > + header.flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET; /* TODO */
> > + header.capsule_image_size = sizeof(header);
> > +
> > + size = fwrite(&header, 1, sizeof(header), f);
> > + if (size < sizeof(header)) {
> > + printf("write failed (%lx)\n", size);
> > + return -1;
> > + }
> > +
> > + /* delete a non-existing variable */
> > + wcharcpy(variable.variable_name, L"FooVar", 9);
> > + variable.vendor_guid = efi_global_variable_guid;
> > + variable.attributes = (EFI_VARIABLE_BOOTSERVICE_ACCESS |
> > + EFI_VARIABLE_RUNTIME_ACCESS);
> > + variable.data_size = 0;
> > + header.capsule_image_size += sizeof(variable) + variable.data_size;
> > +
> > + size = fwrite(&variable, 1, sizeof(variable), f);
> > + if (size < sizeof(variable)) {
> > + printf("write failed (%lx)\n", size);
> > + return -1;
> > + }
> > +
> > + /* update capsule image size */
> > + rewind(f);
> > + size = fwrite(&header, 1, sizeof(header), f);
> > + if (size < sizeof(header)) {
> > + printf("write failed (%lx)\n", size);
> > + return -1;
> > + }
> > +
> > + fclose(f);
> > +
> > + return 0;
> > +}
> > +
> > +void print_usage(void)
> > +{
> > + printf("mkeficapsule [-f <firmware binary> | -t <variable test no>]\n");
> > +}
> > +
> > +/*
> > + * Usage:
> > + * $ mkeficapsule [-f <firmware binary> | -t <variable test no>] <output file>
> > + */
> > +int main(int argc, char **argv)
> > +{
> > + int test_no;
> > +
> > + if (argc != 4) {
> > + print_usage();
> > + return -1;
> > + }
> > +
> > + if (!strcmp(argv[1], "-f")) {
> > + if (create_fwbin(argv[2], argv[3]) < 0) {
> > + printf("Creating firmware capsule for %s failed\n",
> > + argv[2]);
> > + return -1;
> > + }
> > +
> > + return 0;
> > + } else if (!strcmp(argv[1], "-v")) {
> > + test_no = atoi(argv[2]);
> > +
> > + switch (test_no) {
> > + case 1:
> > + if (create_test1(argv[3]) < 0) {
> > + printf("Creating test%02x failed\n", test_no);
> > + return -1;
> > + }
> > + break;
> > + case 2:
> > + if (create_test2(argv[3]) < 0) {
> > + printf("Creating test%02x failed\n", test_no);
> > + return -1;
> > + }
> > + break;
> > + case 3:
> > + if (create_test3(argv[3]) < 0) {
> > + printf("Creating test%02x failed\n", test_no);
> > + return -1;
> > + }
> > + break;
> > + default:
> > + printf("Invalid test number: %s\n", argv[2]);
> > + return -1;
> > + }
> > +
> > + return 0;
> > + }
> > +
> > + print_usage();
> > + return -1;
> > +}
> >
>
next prev parent reply other threads:[~2020-03-18 1:32 UTC|newest]
Thread overview: 49+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-17 2:12 [RFC 00/14] efi_loader: add capsule update support AKASHI Takahiro
2020-03-17 2:12 ` [RFC 01/14] efi_loader: define OsIndicationsSupported flags AKASHI Takahiro
2020-03-17 7:03 ` Heinrich Schuchardt
2020-03-18 1:18 ` AKASHI Takahiro
2020-03-18 18:01 ` Heinrich Schuchardt
2020-03-17 2:12 ` [RFC 02/14] efi_loader: define System Resource Table macros AKASHI Takahiro
2020-03-17 7:06 ` Heinrich Schuchardt
2020-03-18 18:02 ` Heinrich Schuchardt
2020-03-17 2:12 ` [RFC 03/14] efi_loader: export a couple of protocol related functions AKASHI Takahiro
2020-03-17 7:19 ` Heinrich Schuchardt
2020-03-18 18:03 ` Heinrich Schuchardt
2020-03-17 2:12 ` [RFC 04/14] efi_loader: correct a definition of struct efi_capsule_header AKASHI Takahiro
2020-03-17 7:25 ` Heinrich Schuchardt
2020-03-18 18:03 ` Heinrich Schuchardt
2020-03-17 2:12 ` [RFC 05/14] efi_loader: define UpdateCapsule api AKASHI Takahiro
2020-03-17 2:12 ` [RFC 06/14] efi_loader: capsule: add capsule_on_disk support AKASHI Takahiro
2020-03-18 8:55 ` Heinrich Schuchardt
2020-03-19 17:08 ` Heinrich Schuchardt
2020-03-30 7:43 ` AKASHI Takahiro
2020-03-17 2:12 ` [RFC 07/14] efi_loader: capsule: add memory range capsule definitions AKASHI Takahiro
2020-03-17 8:11 ` Heinrich Schuchardt
2020-03-18 1:22 ` AKASHI Takahiro
2020-03-18 7:35 ` Heinrich Schuchardt
2020-03-18 7:57 ` AKASHI Takahiro
2020-04-06 7:48 ` AKASHI Takahiro
2020-03-17 2:12 ` [RFC 08/14] efi_loader: capsule: support firmware update AKASHI Takahiro
2020-03-18 14:09 ` Sughosh Ganu
2020-03-17 2:12 ` [RFC 09/14] efi_loader: add simple firmware management protocol for FIT image AKASHI Takahiro
2020-03-18 8:04 ` Heinrich Schuchardt
2020-03-18 8:17 ` AKASHI Takahiro
2020-03-18 9:06 ` Heinrich Schuchardt
2020-04-06 7:59 ` AKASHI Takahiro
2020-03-17 2:12 ` [RFC 10/14] efi_loader: capsule: support variable update AKASHI Takahiro
2020-03-17 2:12 ` [RFC 11/14] efi_loader: variable: export variables table for runtime access AKASHI Takahiro
2020-03-17 7:37 ` Heinrich Schuchardt
2020-03-18 1:53 ` AKASHI Takahiro
2020-03-19 9:30 ` Ilias Apalodimas
2020-03-18 13:54 ` Sughosh Ganu
2020-03-17 2:12 ` [RFC 12/14] cmd: add "efidebug capsule" command AKASHI Takahiro
2020-03-17 2:12 ` [RFC 13/14] tools: add mkeficapsule command for UEFI capsule update test AKASHI Takahiro
2020-03-17 7:58 ` Heinrich Schuchardt
2020-03-18 1:32 ` AKASHI Takahiro [this message]
2020-03-19 8:55 ` Ilias Apalodimas
2020-03-17 2:12 ` [RFC 14/14] test/py: add efi capsule test AKASHI Takahiro
2020-03-17 7:49 ` [RFC 00/14] efi_loader: add capsule update support Heinrich Schuchardt
2020-03-18 2:04 ` AKASHI Takahiro
2020-03-31 4:36 ` AKASHI Takahiro
2020-04-14 4:38 ` AKASHI Takahiro
2020-03-18 18:16 ` Sughosh Ganu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200318013237.GR13880@linaro.org \
--to=takahiro.akashi@linaro.org \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.