diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/Makefile | 3 | ||||
-rw-r--r-- | tools/imagetool.h | 1 | ||||
-rw-r--r-- | tools/mkimage.c | 23 | ||||
-rw-r--r-- | tools/rkcommon.c | 72 | ||||
-rw-r--r-- | tools/rkcommon.h | 28 | ||||
-rw-r--r-- | tools/rkimage.c | 65 | ||||
-rw-r--r-- | tools/rksd.c | 97 | ||||
-rw-r--r-- | tools/rkspi.c | 119 |
8 files changed, 397 insertions, 11 deletions
diff --git a/tools/Makefile b/tools/Makefile index f673258..9082bda 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -64,6 +64,8 @@ RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \ rsa-sign.o rsa-verify.o rsa-checksum.o \ rsa-mod-exp.o) +ROCKCHIP_OBS = lib/rc4.o rkcommon.o rkimage.o rksd.o + # common objs for dumpimage and mkimage dumpimage-mkimage-objs := aisimage.o \ atmelimage.o \ @@ -90,6 +92,7 @@ dumpimage-mkimage-objs := aisimage.o \ os_support.o \ pblimage.o \ pbl_crc32.o \ + $(ROCKCHIP_OBS) \ socfpgaimage.o \ lib/sha1.o \ lib/sha256.o \ diff --git a/tools/imagetool.h b/tools/imagetool.h index 99bbf2f..ad2deb5 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -60,6 +60,7 @@ struct image_tool_params { const char *comment; /* Comment to add to signature node */ int require_keys; /* 1 to mark signing keys as 'required' */ int file_size; /* Total size of output file */ + int orig_file_size; /* Original size for file before padding */ }; /* diff --git a/tools/mkimage.c b/tools/mkimage.c index e81d455..c50af05 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -488,12 +488,6 @@ copy_file (int ifd, const char *datafile, int pad) int size; struct image_type_params *tparams = imagetool_get_type(params.type); - if (pad >= sizeof(zeros)) { - fprintf(stderr, "%s: Can't pad to %d\n", - params.cmdname, pad); - exit(EXIT_FAILURE); - } - memset(zeros, 0, sizeof(zeros)); if (params.vflag) { @@ -563,11 +557,18 @@ copy_file (int ifd, const char *datafile, int pad) exit (EXIT_FAILURE); } } else if (pad > 1) { - if (write(ifd, (char *)&zeros, pad) != pad) { - fprintf(stderr, "%s: Write error on %s: %s\n", - params.cmdname, params.imagefile, - strerror(errno)); - exit(EXIT_FAILURE); + while (pad > 0) { + int todo = sizeof(zeros); + + if (todo > pad) + todo = pad; + if (write(ifd, (char *)&zeros, todo) != todo) { + fprintf(stderr, "%s: Write error on %s: %s\n", + params.cmdname, params.imagefile, + strerror(errno)); + exit(EXIT_FAILURE); + } + pad -= todo; } } diff --git a/tools/rkcommon.c b/tools/rkcommon.c new file mode 100644 index 0000000..4389622 --- /dev/null +++ b/tools/rkcommon.c @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Helper functions for Rockchip images + */ + +#include "imagetool.h" +#include <image.h> +#include <rc4.h> +#include "mkimage.h" +#include "rkcommon.h" + +enum { + RK_SIGNATURE = 0x0ff0aa55, +}; + +/** + * struct header0_info - header block for boot ROM + * + * This is stored at SD card block 64 (where each block is 512 bytes, or at + * the start of SPI flash. It is encoded with RC4. + * + * @signature: Signature (must be RKSD_SIGNATURE) + * @disable_rc4: 0 to use rc4 for boot image, 1 to use plain binary + * @code1_offset: Offset in blocks of the SPL code from this header + * block. E.g. 4 means 2KB after the start of this header. + * Other fields are not used by U-Boot + */ +struct header0_info { + uint32_t signature; + uint8_t reserved[4]; + uint32_t disable_rc4; + uint16_t code1_offset; + uint16_t code2_offset; + uint8_t reserved1[490]; + uint16_t usflashdatasize; + uint16_t ucflashbootsize; + uint8_t reserved2[2]; +}; + +static unsigned char rc4_key[16] = { + 124, 78, 3, 4, 85, 5, 9, 7, + 45, 44, 123, 56, 23, 13, 23, 17 +}; + +int rkcommon_set_header(void *buf, uint file_size) +{ + struct header0_info *hdr; + + if (file_size > RK_MAX_CODE1_SIZE) + return -ENOSPC; + + memset(buf, '\0', RK_CODE1_OFFSET * RK_BLK_SIZE); + hdr = (struct header0_info *)buf; + hdr->signature = RK_SIGNATURE; + hdr->disable_rc4 = 1; + hdr->code1_offset = RK_CODE1_OFFSET; + hdr->code2_offset = 8; + + hdr->usflashdatasize = (file_size + RK_BLK_SIZE - 1) / RK_BLK_SIZE; + hdr->usflashdatasize = (hdr->usflashdatasize + 3) & ~3; + hdr->ucflashbootsize = hdr->usflashdatasize; + + debug("size=%x, %x\n", params->file_size, hdr->usflashdatasize); + + rc4_encode(buf, RK_BLK_SIZE, rc4_key); + + return 0; +} diff --git a/tools/rkcommon.h b/tools/rkcommon.h new file mode 100644 index 0000000..57fd726 --- /dev/null +++ b/tools/rkcommon.h @@ -0,0 +1,28 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _RKCOMMON_H +#define _RKCOMMON_H + +enum { + RK_BLK_SIZE = 512, + RK_CODE1_OFFSET = 4, + RK_MAX_CODE1_SIZE = 32 << 10, +}; + +/** + * rkcommon_set_header() - set up the header for a Rockchip boot image + * + * This sets up a 2KB header which can be interpreted by the Rockchip boot ROM. + * + * @buf: Pointer to header place (must be at least 2KB in size) + * @file_size: Size of the file we want the boot ROM to load, in bytes + * @return 0 if OK, -ENOSPC if too large + */ +int rkcommon_set_header(void *buf, uint file_size); + +#endif diff --git a/tools/rkimage.c b/tools/rkimage.c new file mode 100644 index 0000000..7b292f4 --- /dev/null +++ b/tools/rkimage.c @@ -0,0 +1,65 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + * + * See README.rockchip for details of the rkimage format + */ + +#include "imagetool.h" +#include <image.h> + +static uint32_t header; + +static int rkimage_check_params(struct image_tool_params *params) +{ + return 0; +} + +static int rkimage_verify_header(unsigned char *buf, int size, + struct image_tool_params *params) +{ + return 0; +} + +static void rkimage_print_header(const void *buf) +{ +} + +static void rkimage_set_header(void *buf, struct stat *sbuf, int ifd, + struct image_tool_params *params) +{ + memcpy(buf, "RK32", 4); +} + +static int rkimage_extract_subimage(void *buf, struct image_tool_params *params) +{ + return 0; +} + +static int rkimage_check_image_type(uint8_t type) +{ + if (type == IH_TYPE_RKIMAGE) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; +} + +/* + * rk_image parameters + */ +U_BOOT_IMAGE_TYPE( + rkimage, + "Rockchip Boot Image support", + 4, + &header, + rkimage_check_params, + rkimage_verify_header, + rkimage_print_header, + rkimage_set_header, + rkimage_extract_subimage, + rkimage_check_image_type, + NULL, + NULL +); diff --git a/tools/rksd.c b/tools/rksd.c new file mode 100644 index 0000000..a8dbe98 --- /dev/null +++ b/tools/rksd.c @@ -0,0 +1,97 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + * + * See README.rockchip for details of the rksd format + */ + +#include "imagetool.h" +#include <image.h> +#include <rc4.h> +#include "mkimage.h" +#include "rkcommon.h" + +enum { + RKSD_SPL_HDR_START = RK_CODE1_OFFSET * RK_BLK_SIZE, + RKSD_SPL_START = RKSD_SPL_HDR_START + 4, + RKSD_HEADER_LEN = RKSD_SPL_START, +}; + +static char dummy_hdr[RKSD_HEADER_LEN]; + +static int rksd_check_params(struct image_tool_params *params) +{ + return 0; +} + +static int rksd_verify_header(unsigned char *buf, int size, + struct image_tool_params *params) +{ + return 0; +} + +static void rksd_print_header(const void *buf) +{ +} + +static void rksd_set_header(void *buf, struct stat *sbuf, int ifd, + struct image_tool_params *params) +{ + unsigned int size; + int ret; + + size = params->file_size - RKSD_SPL_HDR_START; + ret = rkcommon_set_header(buf, size); + if (ret) { + /* TODO(sjg@chromium.org): This method should return an error */ + printf("Warning: SPL image is too large (size %#x) and will not boot\n", + size); + } + + memcpy(buf + RKSD_SPL_HDR_START, "RK32", 4); +} + +static int rksd_extract_subimage(void *buf, struct image_tool_params *params) +{ + return 0; +} + +static int rksd_check_image_type(uint8_t type) +{ + if (type == IH_TYPE_RKSD) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; +} + +/* We pad the file out to a fixed size - this method returns that size */ +static int rksd_vrec_header(struct image_tool_params *params, + struct image_type_params *tparams) +{ + int pad_size; + + pad_size = RKSD_SPL_HDR_START + RK_MAX_CODE1_SIZE; + debug("pad_size %x\n", pad_size); + + return pad_size - params->file_size; +} + +/* + * rk_sd parameters + */ +U_BOOT_IMAGE_TYPE( + rksd, + "Rockchip SD Boot Image support", + RKSD_HEADER_LEN, + dummy_hdr, + rksd_check_params, + rksd_verify_header, + rksd_print_header, + rksd_set_header, + rksd_extract_subimage, + rksd_check_image_type, + NULL, + rksd_vrec_header +); diff --git a/tools/rkspi.c b/tools/rkspi.c new file mode 100644 index 0000000..a3c4c73 --- /dev/null +++ b/tools/rkspi.c @@ -0,0 +1,119 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + * + * SPDX-License-Identifier: GPL-2.0+ + * + * See README.rockchip for details of the rkspi format + */ + +#include "imagetool.h" +#include <image.h> +#include <rc4.h> +#include "mkimage.h" +#include "rkcommon.h" + +enum { + RKSPI_SPL_HDR_START = RK_CODE1_OFFSET * RK_BLK_SIZE, + RKSPI_SPL_START = RKSPI_SPL_HDR_START + 4, + RKSPI_HEADER_LEN = RKSPI_SPL_START, + RKSPI_SECT_LEN = RK_BLK_SIZE * 4, +}; + +static char dummy_hdr[RKSPI_HEADER_LEN]; + +static int rkspi_check_params(struct image_tool_params *params) +{ + return 0; +} + +static int rkspi_verify_header(unsigned char *buf, int size, + struct image_tool_params *params) +{ + return 0; +} + +static void rkspi_print_header(const void *buf) +{ +} + +static void rkspi_set_header(void *buf, struct stat *sbuf, int ifd, + struct image_tool_params *params) +{ + int sector; + unsigned int size; + int ret; + + size = params->orig_file_size; + ret = rkcommon_set_header(buf, size); + debug("size %x\n", size); + if (ret) { + /* TODO(sjg@chromium.org): This method should return an error */ + printf("Warning: SPL image is too large (size %#x) and will not boot\n", + size); + } + + memcpy(buf + RKSPI_SPL_HDR_START, "RK32", 4); + + /* + * Spread the image out so we only use the first 2KB of each 4KB + * region. This is a feature of the SPI format required by the Rockchip + * boot ROM. Its rationale is unknown. + */ + for (sector = size / RKSPI_SECT_LEN - 1; sector >= 0; sector--) { + printf("sector %u\n", sector); + memmove(buf + sector * RKSPI_SECT_LEN * 2, + buf + sector * RKSPI_SECT_LEN, + RKSPI_SECT_LEN); + memset(buf + sector * RKSPI_SECT_LEN * 2 + RKSPI_SECT_LEN, + '\0', RKSPI_SECT_LEN); + } +} + +static int rkspi_extract_subimage(void *buf, struct image_tool_params *params) +{ + return 0; +} + +static int rkspi_check_image_type(uint8_t type) +{ + if (type == IH_TYPE_RKSPI) + return EXIT_SUCCESS; + else + return EXIT_FAILURE; +} + +/* We pad the file out to a fixed size - this method returns that size */ +static int rkspi_vrec_header(struct image_tool_params *params, + struct image_type_params *tparams) +{ + int pad_size; + + pad_size = (RK_MAX_CODE1_SIZE + 0x7ff) / 0x800 * 0x800; + params->orig_file_size = pad_size; + + /* We will double the image size due to the SPI format */ + pad_size *= 2; + pad_size += RKSPI_SPL_HDR_START; + debug("pad_size %x\n", pad_size); + + return pad_size - params->file_size; +} + +/* + * rk_spi parameters + */ +U_BOOT_IMAGE_TYPE( + rkspi, + "Rockchip SPI Boot Image support", + RKSPI_HEADER_LEN, + dummy_hdr, + rkspi_check_params, + rkspi_verify_header, + rkspi_print_header, + rkspi_set_header, + rkspi_extract_subimage, + rkspi_check_image_type, + NULL, + rkspi_vrec_header +); |