diff options
Diffstat (limited to 'tools/stm32image.c')
-rw-r--r-- | tools/stm32image.c | 215 |
1 files changed, 161 insertions, 54 deletions
diff --git a/tools/stm32image.c b/tools/stm32image.c index 5c6991f35de..2a31d37f9cf 100644 --- a/tools/stm32image.c +++ b/tools/stm32image.c @@ -8,58 +8,74 @@ /* magic ='S' 'T' 'M' 0x32 */ #define HEADER_MAGIC be32_to_cpu(0x53544D32) -#define VER_MAJOR_IDX 2 -#define VER_MINOR_IDX 1 -#define VER_VARIANT_IDX 0 +#define VER_MAJOR 2 +#define VER_MINOR 1 +#define VER_VARIANT 0 #define HEADER_VERSION_V1 0x1 +#define HEADER_VERSION_V2 0x2 /* default option : bit0 => no signature */ #define HEADER_DEFAULT_OPTION (cpu_to_le32(0x00000001)) /* default binary type for U-Boot */ #define HEADER_TYPE_UBOOT (cpu_to_le32(0x00000000)) +#define PADDING_HEADER_MAGIC (cpu_to_le32(0xFFFF5453)) +#define PADDING_HEADER_FLAG (1ULL << 31) +#define PADDING_HEADER_LENGTH 0x180 -struct stm32_header { +struct stm32_header_v1 { uint32_t magic_number; - uint32_t image_signature[64 / 4]; + 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; uint32_t load_address; uint32_t reserved2; uint32_t version_number; + /* V1.0 specific content */ uint32_t option_flags; uint32_t ecdsa_algorithm; - uint32_t ecdsa_public_key[64 / 4]; - uint32_t padding[83 / 4]; - uint32_t binary_type; + uint8_t ecdsa_public_key[64]; + uint8_t padding[83]; + uint8_t binary_type; }; -static struct stm32_header stm32image_header; +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; + /* V2.0 specific content */ + 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(struct stm32_header *ptr) -{ - if (!ptr) - return; - - ptr->magic_number = HEADER_MAGIC; - ptr->header_version[VER_MAJOR_IDX] = HEADER_VERSION_V1; - ptr->option_flags = HEADER_DEFAULT_OPTION; - ptr->ecdsa_algorithm = cpu_to_le32(1); - ptr->binary_type = HEADER_TYPE_UBOOT; -} +static struct stm32_header_v1 stm32image_header_v1; +static struct stm32_header_v2 stm32image_header_v2; -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 = start + hdr_len; - len -= hdr_len; + p = (unsigned char *)start + header_size; + len -= header_size; while (len > 0) { csum += *p; @@ -70,24 +86,53 @@ static uint32_t stm32image_checksum(void *start, uint32_t len) return csum; } -static int stm32image_check_image_types(uint8_t type) +static int stm32image_check_image_types_v1(uint8_t type) { if (type == IH_TYPE_STM32IMAGE) return EXIT_SUCCESS; return EXIT_FAILURE; } -static int stm32image_verify_header(unsigned char *ptr, int image_size, - struct image_tool_params *params) +static int stm32image_check_image_types_v2(uint8_t type) +{ + if (type == IH_TYPE_STM32IMAGE_V2) + return EXIT_SUCCESS; + return EXIT_FAILURE; +} + +static int stm32image_verify_header_v1(unsigned char *ptr, int image_size, + struct image_tool_params *params) +{ + struct stm32_header_v1 *stm32hdr = (struct stm32_header_v1 *)ptr; + int i; + + if (image_size < sizeof(struct stm32_header_v1)) + return -1; + if (stm32hdr->magic_number != HEADER_MAGIC) + return -1; + if (stm32hdr->header_version[VER_MAJOR] != HEADER_VERSION_V1) + return -1; + if (stm32hdr->reserved1 || stm32hdr->reserved2) + return -1; + for (i = 0; i < (sizeof(stm32hdr->padding) / 4); i++) { + if (stm32hdr->padding[i] != 0) + return -1; + } + + return 0; +} + +static int stm32image_verify_header_v2(unsigned char *ptr, int image_size, + struct image_tool_params *params) { - struct stm32_header *stm32hdr = (struct stm32_header *)ptr; + struct stm32_header_v2 *stm32hdr = (struct stm32_header_v2 *)ptr; int i; - if (image_size < sizeof(struct stm32_header)) + if (image_size < sizeof(struct stm32_header_v2)) return -1; if (stm32hdr->magic_number != HEADER_MAGIC) return -1; - if (stm32hdr->header_version[VER_MAJOR_IDX] != HEADER_VERSION_V1) + if (stm32hdr->header_version[VER_MAJOR] != HEADER_VERSION_V2) return -1; if (stm32hdr->reserved1 || stm32hdr->reserved2) return -1; @@ -101,38 +146,85 @@ static int stm32image_verify_header(unsigned char *ptr, int image_size, static void stm32image_print_header(const void *ptr, struct image_tool_params *params) { - struct stm32_header *stm32hdr = (struct stm32_header *)ptr; + struct stm32_header_v1 *stm32hdr_v1 = (struct stm32_header_v1 *)ptr; + struct stm32_header_v2 *stm32hdr_v2 = (struct stm32_header_v2 *)ptr; printf("Image Type : STMicroelectronics STM32 V%d.%d\n", - stm32hdr->header_version[VER_MAJOR_IDX], - stm32hdr->header_version[VER_MINOR_IDX]); + stm32hdr_v1->header_version[VER_MAJOR], + stm32hdr_v1->header_version[VER_MINOR]); printf("Image Size : %lu bytes\n", - (unsigned long)le32_to_cpu(stm32hdr->image_length)); + (unsigned long)le32_to_cpu(stm32hdr_v1->image_length)); printf("Image Load : 0x%08x\n", - le32_to_cpu(stm32hdr->load_address)); + le32_to_cpu(stm32hdr_v1->load_address)); printf("Entry Point : 0x%08x\n", - le32_to_cpu(stm32hdr->image_entry_point)); + le32_to_cpu(stm32hdr_v1->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("BinaryType : 0x%08x\n", - le32_to_cpu(stm32hdr->binary_type)); + le32_to_cpu(stm32hdr_v1->image_checksum)); + switch (stm32hdr_v1->header_version[VER_MAJOR]) { + case HEADER_VERSION_V1: + printf("Option : 0x%08x\n", + le32_to_cpu(stm32hdr_v1->option_flags)); + printf("BinaryType : 0x%08x\n", + le32_to_cpu(stm32hdr_v1->binary_type)); + break; + + case HEADER_VERSION_V2: + printf("Extension : 0x%08x\n", + le32_to_cpu(stm32hdr_v2->extension_flags)); + break; + + default: + printf("Incorrect header version\n"); + } } -static void stm32image_set_header(void *ptr, struct stat *sbuf, int ifd, - struct image_tool_params *params) +static void stm32image_set_header_v1(void *ptr, struct stat *sbuf, int ifd, + struct image_tool_params *params) { - struct stm32_header *stm32hdr = (struct stm32_header *)ptr; + struct stm32_header_v1 *stm32hdr = (struct stm32_header_v1 *)ptr; - stm32image_default_header(stm32hdr); + stm32hdr->magic_number = HEADER_MAGIC; + stm32hdr->version_number = cpu_to_le32(0); + + stm32hdr->header_version[VER_MAJOR] = HEADER_VERSION_V1; + stm32hdr->option_flags = HEADER_DEFAULT_OPTION; + stm32hdr->ecdsa_algorithm = cpu_to_le32(1); + stm32hdr->binary_type = HEADER_TYPE_UBOOT; stm32hdr->load_address = cpu_to_le32(params->addr); stm32hdr->image_entry_point = cpu_to_le32(params->ep); stm32hdr->image_length = cpu_to_le32((uint32_t)sbuf->st_size - - sizeof(struct stm32_header)); + sizeof(*stm32hdr)); stm32hdr->image_checksum = - cpu_to_le32(stm32image_checksum(ptr, sbuf->st_size)); + cpu_to_le32(stm32image_checksum(ptr, sbuf->st_size, + sizeof(*stm32hdr))); +} + +static void stm32image_set_header_v2(void *ptr, struct stat *sbuf, int ifd, + struct image_tool_params *params) +{ + struct stm32_header_v2 *stm32hdr = (struct stm32_header_v2 *)ptr; + + stm32hdr->magic_number = HEADER_MAGIC; + stm32hdr->version_number = cpu_to_le32(0); + + stm32hdr->header_version[VER_MAJOR] = HEADER_VERSION_V2; + stm32hdr->extension_flags = + cpu_to_le32(PADDING_HEADER_FLAG); + stm32hdr->extension_headers_length = + cpu_to_le32(PADDING_HEADER_LENGTH); + stm32hdr->extension_header_type = + cpu_to_le32(PADDING_HEADER_MAGIC); + stm32hdr->extension_header_length = + cpu_to_le32(PADDING_HEADER_LENGTH); + + stm32hdr->load_address = cpu_to_le32(params->addr); + stm32hdr->image_entry_point = cpu_to_le32(params->ep); + stm32hdr->image_length = cpu_to_le32((uint32_t)sbuf->st_size - + sizeof(*stm32hdr)); + stm32hdr->image_checksum = + cpu_to_le32(stm32image_checksum(ptr, sbuf->st_size, + sizeof(*stm32hdr))); } /* @@ -141,14 +233,29 @@ static void stm32image_set_header(void *ptr, struct stat *sbuf, int ifd, U_BOOT_IMAGE_TYPE( stm32image, "STMicroelectronics STM32MP Image support", - sizeof(struct stm32_header), - (void *)&stm32image_header, + sizeof(struct stm32_header_v1), + (void *)&stm32image_header_v1, + NULL, + stm32image_verify_header_v1, + stm32image_print_header, + stm32image_set_header_v1, + NULL, + stm32image_check_image_types_v1, + NULL, + NULL +); + +U_BOOT_IMAGE_TYPE( + stm32imagev2, + "STMicroelectronics STM32MP Image V2.0 support", + sizeof(struct stm32_header_v2), + (void *)&stm32image_header_v2, NULL, - stm32image_verify_header, + stm32image_verify_header_v2, stm32image_print_header, - stm32image_set_header, + stm32image_set_header_v2, NULL, - stm32image_check_image_types, + stm32image_check_image_types_v2, NULL, NULL ); |