feat(st): update stm32image tool for header v2

The stm32image tool is updated to manage new header v2.0 for BL2
images.
Add new structure for the header v2.0 management.
Adapt to keep compatibility with v1.0.
Add the header version major and minor in the command line
when executing the tool, as well as binary type (0x10 for BL2).

Change-Id: I70c187e8e7e95b57ab7cfad63df314307a78f1d6
Signed-off-by: Yann Gautier <yann.gautier@st.com>
Signed-off-by: Lionel Debieve <lionel.debieve@st.com>
This commit is contained in:
Nicolas Le Bayon 2019-11-18 17:13:42 +01:00 committed by Yann Gautier
parent 815abebcc1
commit 2d8886acee
2 changed files with 159 additions and 47 deletions

View File

@ -28,6 +28,13 @@ PLAT_XLAT_TABLES_DYNAMIC := 1
STM32MP_DDR_DUAL_AXI_PORT:= 1
STM32MP_DDR_32BIT_INTERFACE:= 1
# STM32 image header version v1.0
STM32_HEADER_VERSION_MAJOR:= 1
STM32_HEADER_VERSION_MINOR:= 0
# STM32 image header binary type for BL2
STM32_HEADER_BL2_BINARY_TYPE:= 0x10
ifeq ($(AARCH32_SP),sp_min)
# Disable Neon support: sp_min runtime may conflict with non-secure world
TF_CFLAGS += -mfloat-abi=soft
@ -427,5 +434,8 @@ tf-a-%.stm32: ${STM32IMAGE} tf-a-%.bin
$(eval ENTRY = $(shell cat $(@:.stm32=.map) | grep "__BL2_IMAGE_START" | awk '{print $$1}'))
${Q}${STM32IMAGE} -s $(word 2,$^) -d $@ \
-l $(LOADADDR) -e ${ENTRY} \
-v ${STM32_TF_VERSION}
-v ${STM32_TF_VERSION} \
-m ${STM32_HEADER_VERSION_MAJOR} \
-n ${STM32_HEADER_VERSION_MINOR} \
-b ${STM32_HEADER_BL2_BINARY_TYPE}
@echo

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2021, STMicroelectronics - All Rights Reserved
* Copyright (c) 2017-2022, STMicroelectronics - All Rights Reserved
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@ -22,16 +22,16 @@
#define VER_MINOR 1
#define VER_VARIANT 0
#define HEADER_VERSION_V1 0x1
#define TF_BINARY_TYPE 0x10
#define HEADER_VERSION_V2 0x2
#define PADDING_HEADER_MAGIC __be32_to_cpu(0x5354FFFF)
#define PADDING_HEADER_FLAG (1 << 31)
#define PADDING_HEADER_LENGTH 0x180
/* Default option : bit0 => no signature */
#define HEADER_DEFAULT_OPTION (__cpu_to_le32(0x00000001))
struct stm32_header {
struct stm32_header_v1 {
uint32_t magic_number;
uint8_t image_signature[64];
uint32_t image_checksum;
uint8_t header_version[4];
uint8_t header_version[4];
uint32_t image_length;
uint32_t image_entry_point;
uint32_t reserved1;
@ -45,31 +45,50 @@ struct stm32_header {
uint8_t binary_type;
};
static void stm32image_default_header(struct stm32_header *ptr)
struct stm32_header_v2 {
uint32_t magic_number;
uint8_t image_signature[64];
uint32_t image_checksum;
uint8_t header_version[4];
uint32_t image_length;
uint32_t image_entry_point;
uint32_t reserved1;
uint32_t load_address;
uint32_t reserved2;
uint32_t version_number;
uint32_t extension_flags;
uint32_t extension_headers_length;
uint32_t binary_type;
uint8_t padding[16];
uint32_t extension_header_type;
uint32_t extension_header_length;
uint8_t extension_padding[376];
};
static void stm32image_default_header(void *ptr)
{
if (!ptr) {
struct stm32_header_v1 *header = (struct stm32_header_v1 *)ptr;
if (!header) {
return;
}
ptr->magic_number = HEADER_MAGIC;
ptr->option_flags = HEADER_DEFAULT_OPTION;
ptr->ecdsa_algorithm = __cpu_to_le32(1);
ptr->version_number = __cpu_to_le32(0);
ptr->binary_type = TF_BINARY_TYPE;
header->magic_number = HEADER_MAGIC;
header->version_number = __cpu_to_le32(0);
}
static uint32_t stm32image_checksum(void *start, uint32_t len)
static uint32_t stm32image_checksum(void *start, uint32_t len,
uint32_t header_size)
{
uint32_t csum = 0;
uint32_t hdr_len = sizeof(struct stm32_header);
uint8_t *p;
if (len < hdr_len) {
if (len < header_size) {
return 0;
}
p = (unsigned char *)start + hdr_len;
len -= hdr_len;
p = (unsigned char *)start + header_size;
len -= header_size;
while (len > 0) {
csum += *p;
@ -82,7 +101,8 @@ static uint32_t stm32image_checksum(void *start, uint32_t len)
static void stm32image_print_header(const void *ptr)
{
struct stm32_header *stm32hdr = (struct stm32_header *)ptr;
struct stm32_header_v1 *stm32hdr = (struct stm32_header_v1 *)ptr;
struct stm32_header_v2 *stm32hdr_v2 = (struct stm32_header_v2 *)ptr;
printf("Image Type : ST Microelectronics STM32 V%d.%d\n",
stm32hdr->header_version[VER_MAJOR],
@ -95,40 +115,87 @@ static void stm32image_print_header(const void *ptr)
__le32_to_cpu(stm32hdr->image_entry_point));
printf("Checksum : 0x%08x\n",
__le32_to_cpu(stm32hdr->image_checksum));
printf("Option : 0x%08x\n",
__le32_to_cpu(stm32hdr->option_flags));
printf("Version : 0x%08x\n",
switch (stm32hdr->header_version[VER_MAJOR]) {
case HEADER_VERSION_V1:
printf("Option : 0x%08x\n",
__le32_to_cpu(stm32hdr->option_flags));
break;
case HEADER_VERSION_V2:
printf("Extension : 0x%08x\n",
__le32_to_cpu(stm32hdr_v2->extension_flags));
break;
default:
printf("Incorrect header version\n");
}
printf("Version : 0x%08x\n",
__le32_to_cpu(stm32hdr->version_number));
}
static void stm32image_set_header(void *ptr, struct stat *sbuf, int ifd,
uint32_t loadaddr, uint32_t ep, uint32_t ver,
uint32_t major, uint32_t minor)
static int stm32image_set_header(void *ptr, struct stat *sbuf, int ifd,
uint32_t loadaddr, uint32_t ep, uint32_t ver,
uint32_t major, uint32_t minor,
uint32_t binary_type, uint32_t header_size)
{
struct stm32_header *stm32hdr = (struct stm32_header *)ptr;
struct stm32_header_v1 *stm32hdr = (struct stm32_header_v1 *)ptr;
struct stm32_header_v2 *stm32hdr_v2 = (struct stm32_header_v2 *)ptr;
uint32_t ext_size = 0U;
uint32_t ext_flags = 0U;
stm32image_default_header(stm32hdr);
stm32image_default_header(ptr);
stm32hdr->header_version[VER_MAJOR] = major;
stm32hdr->header_version[VER_MINOR] = minor;
stm32hdr->load_address = __cpu_to_le32(loadaddr);
stm32hdr->image_entry_point = __cpu_to_le32(ep);
stm32hdr->image_length = __cpu_to_le32((uint32_t)sbuf->st_size -
sizeof(struct stm32_header));
header_size);
stm32hdr->image_checksum =
__cpu_to_le32(stm32image_checksum(ptr, sbuf->st_size));
__cpu_to_le32(stm32image_checksum(ptr, sbuf->st_size,
header_size));
switch (stm32hdr->header_version[VER_MAJOR]) {
case HEADER_VERSION_V1:
/* Default option for header v1 : bit0 => no signature */
stm32hdr->option_flags = __cpu_to_le32(0x00000001);
stm32hdr->ecdsa_algorithm = __cpu_to_le32(1);
stm32hdr->binary_type = (uint8_t)binary_type;
break;
case HEADER_VERSION_V2:
stm32hdr_v2->binary_type = binary_type;
ext_size += PADDING_HEADER_LENGTH;
ext_flags |= PADDING_HEADER_FLAG;
stm32hdr_v2->extension_flags =
__cpu_to_le32(ext_flags);
stm32hdr_v2->extension_headers_length =
__cpu_to_le32(ext_size);
stm32hdr_v2->extension_header_type = PADDING_HEADER_MAGIC;
stm32hdr_v2->extension_header_length =
__cpu_to_le32(PADDING_HEADER_LENGTH);
break;
default:
return -1;
}
stm32hdr->version_number = __cpu_to_le32(ver);
return 0;
}
static int stm32image_create_header_file(char *srcname, char *destname,
uint32_t loadaddr, uint32_t entry,
uint32_t version, uint32_t major,
uint32_t minor)
uint32_t minor, uint32_t binary_type)
{
int src_fd, dest_fd;
int src_fd, dest_fd, header_size;
struct stat sbuf;
unsigned char *ptr;
struct stm32_header stm32image_header;
void *stm32image_header;
dest_fd = open(destname, O_RDWR | O_CREAT | O_TRUNC | O_APPEND, 0666);
if (dest_fd == -1) {
@ -154,15 +221,32 @@ static int stm32image_create_header_file(char *srcname, char *destname,
return -1;
}
memset(&stm32image_header, 0, sizeof(struct stm32_header));
switch (major) {
case HEADER_VERSION_V1:
stm32image_header = malloc(sizeof(struct stm32_header_v1));
header_size = sizeof(struct stm32_header_v1);
break;
if (write(dest_fd, &stm32image_header, sizeof(struct stm32_header)) !=
sizeof(struct stm32_header)) {
fprintf(stderr, "Write error %s: %s\n", destname,
strerror(errno));
case HEADER_VERSION_V2:
stm32image_header = malloc(sizeof(struct stm32_header_v2));
header_size = sizeof(struct stm32_header_v2);
break;
default:
return -1;
}
memset(stm32image_header, 0, header_size);
if (write(dest_fd, stm32image_header, header_size) !=
header_size) {
fprintf(stderr, "Write error %s: %s\n", destname,
strerror(errno));
free(stm32image_header);
return -1;
}
free(stm32image_header);
if (write(dest_fd, ptr, sbuf.st_size) != sbuf.st_size) {
fprintf(stderr, "Write error on %s: %s\n", destname,
strerror(errno));
@ -184,8 +268,11 @@ static int stm32image_create_header_file(char *srcname, char *destname,
return -1;
}
stm32image_set_header(ptr, &sbuf, dest_fd, loadaddr, entry, version,
major, minor);
if (stm32image_set_header(ptr, &sbuf, dest_fd, loadaddr,
entry, version, major, minor,
binary_type, header_size) != 0) {
return -1;
}
stm32image_print_header(ptr);
@ -196,13 +283,22 @@ static int stm32image_create_header_file(char *srcname, char *destname,
int main(int argc, char *argv[])
{
int opt, loadaddr = -1, entry = -1, err = 0, version = 0;
int major = HEADER_VERSION_V1;
int opt;
int loadaddr = -1;
int entry = -1;
int err = 0;
int version = 0;
int binary_type = -1;
int major = HEADER_VERSION_V2;
int minor = 0;
char *dest = NULL, *src = NULL;
char *dest = NULL;
char *src = NULL;
while ((opt = getopt(argc, argv, ":s:d:l:e:v:m:n:")) != -1) {
while ((opt = getopt(argc, argv, ":b:s:d:l:e:v:m:n:")) != -1) {
switch (opt) {
case 'b':
binary_type = strtol(optarg, NULL, 0);
break;
case 's':
src = optarg;
break;
@ -226,7 +322,7 @@ int main(int argc, char *argv[])
break;
default:
fprintf(stderr,
"Usage : %s [-s srcfile] [-d destfile] [-l loadaddr] [-e entry_point] [-m major] [-n minor]\n",
"Usage : %s [-s srcfile] [-d destfile] [-l loadaddr] [-e entry_point] [-m major] [-n minor] [-b binary_type]\n",
argv[0]);
return -1;
}
@ -252,8 +348,14 @@ int main(int argc, char *argv[])
return -1;
}
if (binary_type == -1) {
fprintf(stderr, "Missing -b option\n");
return -1;
}
err = stm32image_create_header_file(src, dest, loadaddr,
entry, version, major, minor);
entry, version, major, minor,
binary_type);
return err;
}