mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-30 08:03:32 +08:00
bce8837071
Add mkimage support for generating and verifying MXS bootstream. The implementation here is mostly a glue code between MXSSB v0.4 and mkimage, but the long-term goal is to rectify this and merge MXSSB with mkimage more tightly. Once this code is properly in U-Boot, MXSSB shall be deprecated in favor of mkimage-mxsimage support. Note that the mxsimage generator needs libcrypto from OpenSSL, I therefore enabled the libcrypto/libssl unconditionally. MXSSB: http://git.denx.de/?p=mxssb.git;a=summary The code is based on research presented at: http://www.rockbox.org/wiki/SbFileFormat Signed-off-by: Marek Vasut <marex@denx.de> Cc: Tom Rini <trini@ti.com> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Stefano Babic <sbabic@denx.de> Cc: Otavio Salvador <otavio@ossystems.com.br>
231 lines
5.1 KiB
C
231 lines
5.1 KiB
C
/*
|
|
* Freescale i.MX28 SB image generator
|
|
*
|
|
* Copyright (C) 2012 Marek Vasut <marex@denx.de>
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
#ifndef __MXSSB_H__
|
|
#define __MXSSB_H__
|
|
|
|
#include <stdint.h>
|
|
#include <arpa/inet.h>
|
|
|
|
#define SB_BLOCK_SIZE 16
|
|
|
|
#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
|
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
|
|
|
struct sb_boot_image_version {
|
|
uint16_t major;
|
|
uint16_t pad0;
|
|
uint16_t minor;
|
|
uint16_t pad1;
|
|
uint16_t revision;
|
|
uint16_t pad2;
|
|
};
|
|
|
|
struct sb_boot_image_header {
|
|
union {
|
|
/* SHA1 of the header. */
|
|
uint8_t digest[20];
|
|
struct {
|
|
/* CBC-MAC initialization vector. */
|
|
uint8_t iv[16];
|
|
uint8_t extra[4];
|
|
};
|
|
};
|
|
/* 'STMP' */
|
|
uint8_t signature1[4];
|
|
/* Major version of the image format. */
|
|
uint8_t major_version;
|
|
/* Minor version of the image format. */
|
|
uint8_t minor_version;
|
|
/* Flags associated with the image. */
|
|
uint16_t flags;
|
|
/* Size of the image in 16b blocks. */
|
|
uint32_t image_blocks;
|
|
/* Offset of the first tag in 16b blocks. */
|
|
uint32_t first_boot_tag_block;
|
|
/* ID of the section to boot from. */
|
|
uint32_t first_boot_section_id;
|
|
/* Amount of crypto keys. */
|
|
uint16_t key_count;
|
|
/* Offset to the key dictionary in 16b blocks. */
|
|
uint16_t key_dictionary_block;
|
|
/* Size of this header in 16b blocks. */
|
|
uint16_t header_blocks;
|
|
/* Amount of section headers. */
|
|
uint16_t section_count;
|
|
/* Section header size in 16b blocks. */
|
|
uint16_t section_header_size;
|
|
/* Padding to align timestamp to uint64_t. */
|
|
uint8_t padding0[2];
|
|
/* 'sgtl' (since v1.1) */
|
|
uint8_t signature2[4];
|
|
/* Image generation date, in microseconds since 1.1.2000 . */
|
|
uint64_t timestamp_us;
|
|
/* Product version. */
|
|
struct sb_boot_image_version
|
|
product_version;
|
|
/* Component version. */
|
|
struct sb_boot_image_version
|
|
component_version;
|
|
/* Drive tag for the system drive. (since v1.1) */
|
|
uint16_t drive_tag;
|
|
/* Padding. */
|
|
uint8_t padding1[6];
|
|
};
|
|
|
|
#define SB_VERSION_MAJOR 1
|
|
#define SB_VERSION_MINOR 1
|
|
|
|
/* Enable to HTLLC verbose boot report. */
|
|
#define SB_IMAGE_FLAG_VERBOSE (1 << 0)
|
|
|
|
struct sb_key_dictionary_key {
|
|
/* The CBC-MAC of image and sections header. */
|
|
uint8_t cbc_mac[SB_BLOCK_SIZE];
|
|
/* The AES key encrypted by image key (zero). */
|
|
uint8_t key[SB_BLOCK_SIZE];
|
|
};
|
|
|
|
struct sb_ivt_header {
|
|
uint32_t header;
|
|
uint32_t entry;
|
|
uint32_t reserved1;
|
|
uint32_t dcd;
|
|
uint32_t boot_data;
|
|
uint32_t self;
|
|
uint32_t csf;
|
|
uint32_t reserved2;
|
|
};
|
|
|
|
#define SB_HAB_IVT_TAG 0xd1UL
|
|
#define SB_HAB_DCD_TAG 0xd2UL
|
|
|
|
#define SB_HAB_VERSION 0x40UL
|
|
|
|
/*
|
|
* The "size" field in the IVT header is not naturally aligned,
|
|
* use this macro to fill first 4 bytes of the IVT header without
|
|
* causing issues on some systems (esp. M68k, PPC, MIPS-BE, ARM-BE).
|
|
*/
|
|
static inline uint32_t sb_hab_ivt_header(void)
|
|
{
|
|
uint32_t ret = 0;
|
|
ret |= SB_HAB_IVT_TAG << 24;
|
|
ret |= sizeof(struct sb_ivt_header) << 16;
|
|
ret |= SB_HAB_VERSION;
|
|
return htonl(ret);
|
|
}
|
|
|
|
struct sb_sections_header {
|
|
/* Section number. */
|
|
uint32_t section_number;
|
|
/* Offset of this sections first instruction after "TAG". */
|
|
uint32_t section_offset;
|
|
/* Size of the section in 16b blocks. */
|
|
uint32_t section_size;
|
|
/* Section flags. */
|
|
uint32_t section_flags;
|
|
};
|
|
|
|
#define SB_SECTION_FLAG_BOOTABLE (1 << 0)
|
|
|
|
struct sb_command {
|
|
struct {
|
|
uint8_t checksum;
|
|
uint8_t tag;
|
|
uint16_t flags;
|
|
#define ROM_TAG_CMD_FLAG_ROM_LAST_TAG 0x1
|
|
#define ROM_LOAD_CMD_FLAG_DCD_LOAD 0x1 /* MX28 only */
|
|
#define ROM_JUMP_CMD_FLAG_HAB 0x1 /* MX28 only */
|
|
#define ROM_CALL_CMD_FLAG_HAB 0x1 /* MX28 only */
|
|
} header;
|
|
|
|
union {
|
|
struct {
|
|
uint32_t reserved[3];
|
|
} nop;
|
|
struct {
|
|
uint32_t section_number;
|
|
uint32_t section_length;
|
|
uint32_t section_flags;
|
|
} tag;
|
|
struct {
|
|
uint32_t address;
|
|
uint32_t count;
|
|
uint32_t crc32;
|
|
} load;
|
|
struct {
|
|
uint32_t address;
|
|
uint32_t count;
|
|
uint32_t pattern;
|
|
} fill;
|
|
struct {
|
|
uint32_t address;
|
|
uint32_t reserved;
|
|
/* Passed in register r0 before JUMP */
|
|
uint32_t argument;
|
|
} jump;
|
|
struct {
|
|
uint32_t address;
|
|
uint32_t reserved;
|
|
/* Passed in register r0 before CALL */
|
|
uint32_t argument;
|
|
} call;
|
|
struct {
|
|
uint32_t reserved1;
|
|
uint32_t reserved2;
|
|
uint32_t mode;
|
|
} mode;
|
|
|
|
};
|
|
};
|
|
|
|
/*
|
|
* Most of the mode names are same or at least similar
|
|
* on i.MX23 and i.MX28, but some of the mode names
|
|
* differ. The "name" field represents the mode name
|
|
* on i.MX28 as seen in Table 12-2 of the datasheet.
|
|
* The "altname" field represents the differently named
|
|
* fields on i.MX23 as seen in Table 35-3 of the
|
|
* datasheet.
|
|
*/
|
|
static const struct {
|
|
const char *name;
|
|
const char *altname;
|
|
const uint8_t mode;
|
|
} modetable[] = {
|
|
{ "USB", NULL, 0x00 },
|
|
{ "I2C", NULL, 0x01 },
|
|
{ "SPI2_FLASH", "SPI1_FLASH", 0x02 },
|
|
{ "SPI3_FLASH", "SPI2_FLASH", 0x03 },
|
|
{ "NAND_BCH", NULL, 0x04 },
|
|
{ "JTAG", NULL, 0x06 },
|
|
{ "SPI3_EEPROM", "SPI2_EEPROM", 0x08 },
|
|
{ "SD_SSP0", NULL, 0x09 },
|
|
{ "SD_SSP1", NULL, 0x0A }
|
|
};
|
|
|
|
enum sb_tag {
|
|
ROM_NOP_CMD = 0x00,
|
|
ROM_TAG_CMD = 0x01,
|
|
ROM_LOAD_CMD = 0x02,
|
|
ROM_FILL_CMD = 0x03,
|
|
ROM_JUMP_CMD = 0x04,
|
|
ROM_CALL_CMD = 0x05,
|
|
ROM_MODE_CMD = 0x06
|
|
};
|
|
|
|
struct sb_source_entry {
|
|
uint8_t tag;
|
|
uint32_t address;
|
|
uint32_t flags;
|
|
char *filename;
|
|
};
|
|
|
|
#endif /* __MXSSB_H__ */
|