From 424b86ae597fa933b94fa91a6683e8c6b47af81d Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 30 Aug 2015 16:55:22 -0600 Subject: mkimage: Allow padding to any length At present there is an arbitrary limit of 4KB for padding. Rockchip needs more than that, so remove this restriction. Signed-off-by: Simon Glass Reviewed-by: Joe Hershberger --- tools/mkimage.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/mkimage.c b/tools/mkimage.c index e81d455083..c50af0510d 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; } } -- cgit From 1b99e5bbb619f91c675306226a262a14c9d9a3a3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 30 Aug 2015 16:55:23 -0600 Subject: mkimage: Allow the original file size to be recorded Allow the image handler to store the original input file size so that it can reference it later. Signed-off-by: Simon Glass Reviewed-by: Joe Hershberger --- tools/imagetool.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/imagetool.h b/tools/imagetool.h index 99bbf2f459..ad2deb58dc 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 */ }; /* -- cgit From a131c1f44231e3546b1cca8480400c98d1dd7ac8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 30 Aug 2015 16:55:24 -0600 Subject: rockchip: Add the rkimage format to mkimage Rockchip SoCs require certain formats for code that they execute, The simplest format is a 4-byte header at the start of a binary file. Add support for this so that we can create images that the boot ROM understands. Signed-off-by: Simon Glass --- tools/Makefile | 3 +++ tools/rkcommon.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/rkcommon.h | 28 ++++++++++++++++++++++ tools/rkimage.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 tools/rkcommon.c create mode 100644 tools/rkcommon.h create mode 100644 tools/rkimage.c (limited to 'tools') diff --git a/tools/Makefile b/tools/Makefile index f673258bad..267f55c933 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 + # 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/rkcommon.c b/tools/rkcommon.c new file mode 100644 index 0000000000..43896226c0 --- /dev/null +++ b/tools/rkcommon.c @@ -0,0 +1,72 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Helper functions for Rockchip images + */ + +#include "imagetool.h" +#include +#include +#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 0000000000..57fd726004 --- /dev/null +++ b/tools/rkcommon.h @@ -0,0 +1,28 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass + * + * 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 0000000000..7b292f4235 --- /dev/null +++ b/tools/rkimage.c @@ -0,0 +1,65 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + * + * See README.rockchip for details of the rkimage format + */ + +#include "imagetool.h" +#include + +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 +); -- cgit From f9a3c278b98a17eddbf0ad903689cce47e3e6f47 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 30 Aug 2015 16:55:25 -0600 Subject: rockchip: Add support for the SD image The Rockchip boot ROM requires a particular file format. It consists of 64KB of zeroes, a 512-byte header encoded with RC4, and then some executable code. Add support to mkimage so that an SPL image (u-boot-spl-dtb.bin) can be converted to this format. Signed-off-by: Simon Glass --- tools/Makefile | 2 +- tools/rksd.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 tools/rksd.c (limited to 'tools') diff --git a/tools/Makefile b/tools/Makefile index 267f55c933..9082bda219 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -64,7 +64,7 @@ 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 +ROCKCHIP_OBS = lib/rc4.o rkcommon.o rkimage.o rksd.o # common objs for dumpimage and mkimage dumpimage-mkimage-objs := aisimage.o \ diff --git a/tools/rksd.c b/tools/rksd.c new file mode 100644 index 0000000000..2efcd68c3a --- /dev/null +++ b/tools/rksd.c @@ -0,0 +1,102 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + * + * See README.rockchip for details of the rksd format + */ + +#include "imagetool.h" +#include +#include +#include "mkimage.h" +#include "rkcommon.h" + +enum { + RKSD_HEADER0_START = 64 * RK_BLK_SIZE, + RKSD_SPL_HDR_START = RKSD_HEADER0_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; + + /* Zero the whole header. The first 32KB is empty */ + memset(buf, '\0', RKSD_HEADER0_START); + + size = params->file_size - RKSD_SPL_HDR_START; + ret = rkcommon_set_header(buf + RKSD_HEADER0_START, 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 +); -- cgit From 10b84fe1b59b4f8b485057b911f2d5bdd9b1c9a4 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 30 Aug 2015 16:55:26 -0600 Subject: rockchip: Add support for the SPI image The Rockchip boot ROM requires a particular file format for booting from SPI. It consists of a 512-byte header encoded with RC4, some padding and then up to 32KB of executable code in 2KB blocks, separated by 2KB empty blocks. Add support to mkimage so that an SPL image (u-boot-spl-dtb.bin) can be converted to this format. This allows booting from SPI flash on supported machines. Signed-off-by: Simon Glass --- tools/rkspi.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 tools/rkspi.c (limited to 'tools') diff --git a/tools/rkspi.c b/tools/rkspi.c new file mode 100644 index 0000000000..a3c4c73916 --- /dev/null +++ b/tools/rkspi.c @@ -0,0 +1,119 @@ +/* + * (C) Copyright 2015 Google, Inc + * Written by Simon Glass + * + * SPDX-License-Identifier: GPL-2.0+ + * + * See README.rockchip for details of the rkspi format + */ + +#include "imagetool.h" +#include +#include +#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 +); -- cgit From dd39bcaffbc886e5948d5b6dc0a4156a8b0ba053 Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Sun, 30 Aug 2015 16:55:50 -0600 Subject: rockchip: Drop first 32kb of zeros from the rkSD image type Instead of creating a rockchip SPL SD card image with 32KB of zeros which can be written to the start of an SD card, create the images with only the useful data that should be written to an offset of 32KB on the SD card. The first 32 kilobytes aren't needed for bootup and only serve as convenient way of accidentally obliterating your partition table. Signed-off-by: Sjoerd Simons Acked-by: Simon Glass Signed-off-by: Simon Glass --- tools/rksd.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/rksd.c b/tools/rksd.c index 2efcd68c3a..a8dbe98750 100644 --- a/tools/rksd.c +++ b/tools/rksd.c @@ -14,9 +14,7 @@ #include "rkcommon.h" enum { - RKSD_HEADER0_START = 64 * RK_BLK_SIZE, - RKSD_SPL_HDR_START = RKSD_HEADER0_START + - RK_CODE1_OFFSET * RK_BLK_SIZE, + RKSD_SPL_HDR_START = RK_CODE1_OFFSET * RK_BLK_SIZE, RKSD_SPL_START = RKSD_SPL_HDR_START + 4, RKSD_HEADER_LEN = RKSD_SPL_START, }; @@ -44,11 +42,8 @@ static void rksd_set_header(void *buf, struct stat *sbuf, int ifd, unsigned int size; int ret; - /* Zero the whole header. The first 32KB is empty */ - memset(buf, '\0', RKSD_HEADER0_START); - size = params->file_size - RKSD_SPL_HDR_START; - ret = rkcommon_set_header(buf + RKSD_HEADER0_START, size); + 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", -- cgit