ARM: mxs: tools: Add mkimage support for MXS bootstream
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>
This commit is contained in:
parent
b83c709e8d
commit
bce8837071
6
arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg
Normal file
6
arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg
Normal file
@ -0,0 +1,6 @@
|
||||
SECTION 0x0 BOOTABLE
|
||||
TAG LAST
|
||||
LOAD 0x0 spl/u-boot-spl.bin
|
||||
CALL 0x14 0x0
|
||||
LOAD 0x40000100 u-boot.bin
|
||||
CALL 0x40000100 0x0
|
8
arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg
Normal file
8
arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg
Normal file
@ -0,0 +1,8 @@
|
||||
SECTION 0x0 BOOTABLE
|
||||
TAG LAST
|
||||
LOAD 0x0 spl/u-boot-spl.bin
|
||||
LOAD IVT 0x8000 0x14
|
||||
CALL HAB 0x8000 0x0
|
||||
LOAD 0x40000100 u-boot.bin
|
||||
LOAD IVT 0x8000 0x40000100
|
||||
CALL HAB 0x8000 0x0
|
@ -135,6 +135,7 @@ static const table_entry_t uimage_type[] = {
|
||||
{ IH_TYPE_SCRIPT, "script", "Script", },
|
||||
{ IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
|
||||
{ IH_TYPE_UBLIMAGE, "ublimage", "Davinci UBL image",},
|
||||
{ IH_TYPE_MXSIMAGE, "mxsimage", "Freescale MXS Boot Image",},
|
||||
{ -1, "", "", },
|
||||
};
|
||||
|
||||
|
@ -194,6 +194,15 @@ LDFLAGS_FINAL += --gc-sections
|
||||
endif
|
||||
|
||||
# TODO(sjg@chromium.org): Is this correct on Mac OS?
|
||||
|
||||
# MXSImage needs LibSSL
|
||||
ifneq ($(CONFIG_MX23)$(CONFIG_MX28),)
|
||||
HOSTLIBS += -lssl -lcrypto
|
||||
# Add CONFIG_MXS into host CFLAGS, so we can check whether or not register
|
||||
# the mxsimage support within tools/mxsimage.c .
|
||||
HOSTCFLAGS += -DCONFIG_MXS
|
||||
endif
|
||||
|
||||
ifdef CONFIG_FIT_SIGNATURE
|
||||
HOSTLIBS += -lssl -lcrypto
|
||||
|
||||
|
165
doc/README.mxsimage
Normal file
165
doc/README.mxsimage
Normal file
@ -0,0 +1,165 @@
|
||||
Freescale i.MX233/i.MX28 SB image generator via mkimage
|
||||
=======================================================
|
||||
|
||||
This tool allows user to produce SB BootStream encrypted with a zero key.
|
||||
Such a BootStream is then bootable on i.MX23/i.MX28.
|
||||
|
||||
Usage -- producing image:
|
||||
=========================
|
||||
The mxsimage tool is targeted to be a simple replacement for the elftosb2 .
|
||||
To generate an image, write an image configuration file and run:
|
||||
|
||||
mkimage -A arm -O u-boot -T mxsimage -n <path to configuration file> \
|
||||
<output bootstream file>
|
||||
|
||||
The output bootstream file is usually using the .sb file extension. Note
|
||||
that the example configuration files for producing bootable BootStream with
|
||||
the U-Boot bootloader can be found under arch/arm/boot/cpu/arm926ejs/mxs/
|
||||
directory. See the following files:
|
||||
|
||||
mxsimage.mx23.cfg -- This is an example configuration for i.MX23
|
||||
mxsimage.mx28.cfg -- This is an example configuration for i.MX28
|
||||
|
||||
Each configuration file uses very simple instruction semantics and a few
|
||||
additional rules have to be followed so that a useful image can be produced.
|
||||
These semantics and rules will be outlined now.
|
||||
|
||||
- Each line of the configuration file contains exactly one instruction.
|
||||
- Every numeric value must be encoded in hexadecimal and in format 0xabcdef12 .
|
||||
- The configuration file is a concatenation of blocks called "sections" and
|
||||
optionally "DCD blocks" (see below).
|
||||
- Each "section" is started by the "SECTION" instruction.
|
||||
- The "SECTION" instruction has the following semantics:
|
||||
|
||||
SECTION u32_section_number [BOOTABLE]
|
||||
- u32_section_number :: User-selected ID of the section
|
||||
- BOOTABLE :: Sets the section as bootable
|
||||
|
||||
- A bootable section is one from which the BootROM starts executing
|
||||
subsequent instructions or code. Exactly one section must be selected
|
||||
as bootable, usually the one containing the instructions and data to
|
||||
load the bootloader.
|
||||
|
||||
- A "SECTION" must be immediatelly followed by a "TAG" instruction.
|
||||
- The "TAG" instruction has the following semantics:
|
||||
|
||||
TAG [LAST]
|
||||
- LAST :: Flag denoting the last section in the file
|
||||
|
||||
- After a "TAG" unstruction, any of the following instructions may follow
|
||||
in any order and any quantity:
|
||||
|
||||
NOOP
|
||||
- This instruction does nothing
|
||||
|
||||
LOAD u32_address string_filename
|
||||
- Instructs the BootROM to load file pointed by "string_filename" onto
|
||||
address "u32_address".
|
||||
|
||||
LOAD IVT u32_address u32_IVT_entry_point
|
||||
- Crafts and loads IVT onto address "u32_address" with the entry point
|
||||
of u32_IVT_entry_point.
|
||||
- i.MX28-specific instruction!
|
||||
|
||||
LOAD DCD u32_address u32_DCD_block_ID
|
||||
- Loads the DCD block with ID "u32_DCD_block_ID" onto address
|
||||
"u32_address" and executes the contents of this DCD block
|
||||
- i.MX28-specific instruction!
|
||||
|
||||
FILL u32_address u32_pattern u32_length
|
||||
- Starts to write memory from addres "u32_address" with a pattern
|
||||
specified by "u32_pattern". Writes exactly "u32_length" bytes of the
|
||||
pattern.
|
||||
|
||||
JUMP [HAB] u32_address [u32_r0_arg]
|
||||
- Jumps onto memory address specified by "u32_address" by setting this
|
||||
address in PT. The BootROM will pass the "u32_r0_arg" value in ARM
|
||||
register "r0" to the executed code if this option is specified.
|
||||
Otherwise, ARM register "r0" will default to value 0x00000000. The
|
||||
optional "HAB" flag is i.MX28-specific flag turning on the HAB boot.
|
||||
|
||||
CALL [HAB] u32_address [u32_r0_arg]
|
||||
- See JUMP instruction above, as the operation is exactly the same with
|
||||
one difference. The CALL instruction does allow returning into the
|
||||
BootROM from the executed code. U-Boot makes use of this in it's SPL
|
||||
code.
|
||||
|
||||
MODE string_mode
|
||||
- Restart the CPU and start booting from device specified by the
|
||||
"string_mode" argument. The "string_mode" differs for each CPU
|
||||
and can be:
|
||||
i.MX23, string_mode = USB/I2C/SPI1_FLASH/SPI2_FLASH/NAND_BCH
|
||||
JTAG/SPI3_EEPROM/SD_SSP0/SD_SSP1
|
||||
i.MX28, string_mode = USB/I2C/SPI2_FLASH/SPI3_FLASH/NAND_BCH
|
||||
JTAG/SPI2_EEPROM/SD_SSP0/SD_SSP1
|
||||
|
||||
- An optional "DCD" blocks can be added at the begining of the configuration
|
||||
file. Note that the DCD is only supported on i.MX28.
|
||||
- The DCD blocks must be inserted before the first "section" in the
|
||||
configuration file.
|
||||
- The DCD block has the following semantics:
|
||||
|
||||
DCD u32_DCD_block_ID
|
||||
- u32_DCD_block_ID :: The ID number of the DCD block, must match
|
||||
the ID number used by "LOAD DCD" instruction.
|
||||
|
||||
- The DCD block must be followed by one of the following instructions. All
|
||||
of the instructions operate either on 1, 2 or 4 bytes. This is selected by
|
||||
the 'n' suffix of the instruction:
|
||||
|
||||
WRITE.n u32_address u32_value
|
||||
- Write the "u32_value" to the "u32_address" address.
|
||||
|
||||
ORR.n u32_address u32_value
|
||||
- Read the "u32_address", perform a bitwise-OR with the "u32_value" and
|
||||
write the result back to "u32_address".
|
||||
|
||||
ANDC.n u32_address u32_value
|
||||
- Read the "u32_address", perform a bitwise-AND with the complement of
|
||||
"u32_value" and write the result back to "u32_address".
|
||||
|
||||
EQZ.n u32_address u32_count
|
||||
- Read the "u32_address" at most "u32_count" times and test if the value
|
||||
read is zero. If it is, break the loop earlier.
|
||||
|
||||
NEZ.n u32_address u32_count
|
||||
- Read the "u32_address" at most "u32_count" times and test if the value
|
||||
read is non-zero. If it is, break the loop earlier.
|
||||
|
||||
EQ.n u32_address u32_mask
|
||||
- Read the "u32_address" in a loop and test if the result masked with
|
||||
"u32_mask" equals the "u32_mask". If the values are equal, break the
|
||||
reading loop.
|
||||
|
||||
NEQ.n u32_address u32_mask
|
||||
- Read the "u32_address" in a loop and test if the result masked with
|
||||
"u32_mask" does not equal the "u32_mask". If the values are not equal,
|
||||
break the reading loop.
|
||||
|
||||
NOOP
|
||||
- This instruction does nothing.
|
||||
|
||||
- If the verbose output from the BootROM is enabled, the BootROM will produce a
|
||||
letter on the Debug UART for each instruction it started processing. Here is a
|
||||
mapping between the above instructions and the BootROM verbose output:
|
||||
|
||||
H -- SB Image header loaded
|
||||
T -- TAG instruction
|
||||
N -- NOOP instruction
|
||||
L -- LOAD instruction
|
||||
F -- FILL instruction
|
||||
J -- JUMP instruction
|
||||
C -- CALL instruction
|
||||
M -- MODE instruction
|
||||
|
||||
Usage -- verifying image:
|
||||
=========================
|
||||
|
||||
The mxsimage can also verify and dump contents of an image. Use the following
|
||||
syntax to verify and dump contents of an image:
|
||||
|
||||
mkimage -l <input bootstream file>
|
||||
|
||||
This will output all the information from the SB image header and all the
|
||||
instructions contained in the SB image. It will also check if the various
|
||||
checksums in the SB image are correct.
|
@ -212,6 +212,7 @@ struct lmb;
|
||||
#define IH_TYPE_AISIMAGE 13 /* TI Davinci AIS Image */
|
||||
#define IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image, can run from any load address */
|
||||
#define IH_TYPE_PBLIMAGE 15 /* Freescale PBL Boot Image */
|
||||
#define IH_TYPE_MXSIMAGE 16 /* Freescale MXSBoot Image */
|
||||
|
||||
/*
|
||||
* Compression Types
|
||||
|
@ -83,6 +83,7 @@ NOPED_OBJ_FILES-y += aisimage.o
|
||||
NOPED_OBJ_FILES-y += kwbimage.o
|
||||
NOPED_OBJ_FILES-y += pblimage.o
|
||||
NOPED_OBJ_FILES-y += imximage.o
|
||||
NOPED_OBJ_FILES-y += mxsimage.o
|
||||
NOPED_OBJ_FILES-y += image-host.o
|
||||
NOPED_OBJ_FILES-y += omapimage.o
|
||||
NOPED_OBJ_FILES-y += mkenvimage.o
|
||||
@ -209,6 +210,7 @@ $(obj)mkimage$(SFX): $(obj)aisimage.o \
|
||||
$(obj)image-host.o \
|
||||
$(FIT_SIG_OBJS) \
|
||||
$(obj)imximage.o \
|
||||
$(obj)mxsimage.o \
|
||||
$(obj)kwbimage.o \
|
||||
$(obj)pblimage.o \
|
||||
$(obj)md5.o \
|
||||
|
@ -145,6 +145,8 @@ main (int argc, char **argv)
|
||||
init_kwb_image_type ();
|
||||
/* Init Freescale imx Boot image generation/list support */
|
||||
init_imx_image_type ();
|
||||
/* Init Freescale mxs Boot image generation/list support */
|
||||
init_mxs_image_type();
|
||||
/* Init FIT image generation/list support */
|
||||
init_fit_image_type ();
|
||||
/* Init TI OMAP Boot image generation/list support */
|
||||
|
@ -161,6 +161,7 @@ void init_pbl_image_type(void);
|
||||
void init_ais_image_type(void);
|
||||
void init_kwb_image_type (void);
|
||||
void init_imx_image_type (void);
|
||||
void init_mxs_image_type(void);
|
||||
void init_default_image_type (void);
|
||||
void init_fit_image_type (void);
|
||||
void init_ubl_image_type(void);
|
||||
|
2347
tools/mxsimage.c
Normal file
2347
tools/mxsimage.c
Normal file
File diff suppressed because it is too large
Load Diff
230
tools/mxsimage.h
Normal file
230
tools/mxsimage.h
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* 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__ */
|
Loading…
Reference in New Issue
Block a user