From d9b58b303120fb8fe0b7c9799e2b7682da4bec16 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 27 Apr 2016 14:03:29 +0200 Subject: tools: zynqmpimage: Add Xilinx ZynqMP boot header generation Add support for the zynqmpimage to mkimage. Only basic functionality is supported without encryption and register initialization with one partition which is filled by U-Boot SPL. For more detail information look at Xilinx ZynqMP TRM. Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- tools/Makefile | 1 + tools/zynqmpimage.c | 269 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 270 insertions(+) create mode 100644 tools/zynqmpimage.c (limited to 'tools') diff --git a/tools/Makefile b/tools/Makefile index da50e1bffca..63355aa36d8 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -98,6 +98,7 @@ dumpimage-mkimage-objs := aisimage.o \ common/hash.o \ ublimage.o \ zynqimage.o \ + zynqmpimage.o \ $(LIBFDT_OBJS) \ $(RSA_OBJS-y) diff --git a/tools/zynqmpimage.c b/tools/zynqmpimage.c new file mode 100644 index 00000000000..3f28eb401d9 --- /dev/null +++ b/tools/zynqmpimage.c @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2016 Michal Simek + * Copyright (C) 2015 Nathan Rossi + * + * SPDX-License-Identifier: GPL-2.0+ + * + * The following Boot Header format/structures and values are defined in the + * following documents: + * * ug1085 ZynqMP TRM (Chapter 9, Table 9-3) + * + * Expected Header Size = 0x9C0 + * Forced as 'little' endian, 32-bit words + * + * 0x 0 - Interrupt table (8 words) + * ... (Default value = 0xeafffffe) + * 0x 1f + * 0x 20 - Width detection + * * DEFAULT_WIDTHDETECTION 0xaa995566 + * 0x 24 - Image identifier + * * DEFAULT_IMAGEIDENTIFIER 0x584c4e58 + * 0x 28 - Encryption + * * 0x00000000 - None + * * 0xa5c3c5a3 - eFuse + * * 0xa5c3c5a7 - obfuscated key in eFUSE + * * 0x3a5c3c5a - bbRam + * * 0xa35c7ca5 - obfuscated key in boot header + * 0x 2C - Image load + * 0x 30 - Image offset + * 0x 34 - PFW image length + * 0x 38 - Total PFW image length + * 0x 3C - Image length + * 0x 40 - Total image length + * 0x 44 - Image attributes + * 0x 48 - Header checksum + * 0x 4c - Obfuscated key + * ... + * 0x 68 + * 0x 6c - Reserved + * 0x 70 - User defined + * ... + * 0x 9c + * 0x a0 - Secure header initialization vector + * ... + * 0x a8 + * 0x ac - Obfuscated key initialization vector + * ... + * 0x b4 + * 0x b8 - Register Initialization, 511 Address and Data word pairs + * * List is terminated with an address of 0xffffffff or + * ... * at the max number of entries + * 0x8b4 + * 0x8b8 - Reserved + * ... + * 0x9bf + * 0x9c0 - Data/Image starts here or above + */ + +#include "imagetool.h" +#include "mkimage.h" +#include + +#define HEADER_INTERRUPT_DEFAULT (cpu_to_le32(0xeafffffe)) +#define HEADER_REGINIT_NULL (cpu_to_le32(0xffffffff)) +#define HEADER_WIDTHDETECTION (cpu_to_le32(0xaa995566)) +#define HEADER_IMAGEIDENTIFIER (cpu_to_le32(0x584c4e58)) + +enum { + ENCRYPTION_EFUSE = 0xa5c3c5a3, + ENCRYPTION_OEFUSE = 0xa5c3c5a7, + ENCRYPTION_BBRAM = 0x3a5c3c5a, + ENCRYPTION_OBBRAM = 0xa35c7ca5, + ENCRYPTION_NONE = 0x0, +}; + +struct zynqmp_reginit { + uint32_t address; + uint32_t data; +}; + +#define HEADER_INTERRUPT_VECTORS 8 +#define HEADER_REGINITS 256 + +struct zynqmp_header { + uint32_t interrupt_vectors[HEADER_INTERRUPT_VECTORS]; /* 0x0 */ + uint32_t width_detection; /* 0x20 */ + uint32_t image_identifier; /* 0x24 */ + uint32_t encryption; /* 0x28 */ + uint32_t image_load; /* 0x2c */ + uint32_t image_offset; /* 0x30 */ + uint32_t pfw_image_length; /* 0x34 */ + uint32_t total_pfw_image_length; /* 0x38 */ + uint32_t image_size; /* 0x3c */ + uint32_t image_stored_size; /* 0x40 */ + uint32_t image_attributes; /* 0x44 */ + uint32_t checksum; /* 0x48 */ + uint32_t __reserved1[27]; /* 0x4c */ + struct zynqmp_reginit register_init[HEADER_REGINITS]; /* 0xb8 */ + uint32_t __reserved4[66]; /* 0x9c0 */ +}; + +static struct zynqmp_header zynqmpimage_header; + +static uint32_t zynqmpimage_checksum(struct zynqmp_header *ptr) +{ + uint32_t checksum = 0; + + if (ptr == NULL) + return 0; + + checksum += le32_to_cpu(ptr->width_detection); + checksum += le32_to_cpu(ptr->image_identifier); + checksum += le32_to_cpu(ptr->encryption); + checksum += le32_to_cpu(ptr->image_load); + checksum += le32_to_cpu(ptr->image_offset); + checksum += le32_to_cpu(ptr->pfw_image_length); + checksum += le32_to_cpu(ptr->total_pfw_image_length); + checksum += le32_to_cpu(ptr->image_size); + checksum += le32_to_cpu(ptr->image_stored_size); + checksum += le32_to_cpu(ptr->image_attributes); + checksum = ~checksum; + + return cpu_to_le32(checksum); +} + +static void zynqmpimage_default_header(struct zynqmp_header *ptr) +{ + int i; + + if (ptr == NULL) + return; + + ptr->width_detection = HEADER_WIDTHDETECTION; + ptr->image_attributes = 0x800; + ptr->image_identifier = HEADER_IMAGEIDENTIFIER; + ptr->encryption = cpu_to_le32(ENCRYPTION_NONE); + + /* Setup not-supported/constant/reserved fields */ + for (i = 0; i < HEADER_INTERRUPT_VECTORS; i++) + ptr->interrupt_vectors[i] = HEADER_INTERRUPT_DEFAULT; + + for (i = 0; i < HEADER_REGINITS; i++) { + ptr->register_init[i].address = HEADER_REGINIT_NULL; + ptr->register_init[i].data = 0; + } + + /* + * Certain reserved fields are required to be set to 0, ensure they are + * set as such. + */ + ptr->pfw_image_length = 0x0; + ptr->total_pfw_image_length = 0x0; +} + +/* mkimage glue functions */ +static int zynqmpimage_verify_header(unsigned char *ptr, int image_size, + struct image_tool_params *params) +{ + struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr; + + if (image_size < sizeof(struct zynqmp_header)) + return -1; + + if (zynqhdr->width_detection != HEADER_WIDTHDETECTION) + return -1; + if (zynqhdr->image_identifier != HEADER_IMAGEIDENTIFIER) + return -1; + + if (zynqmpimage_checksum(zynqhdr) != zynqhdr->checksum) + return -1; + + return 0; +} + +static void zynqmpimage_print_header(const void *ptr) +{ + struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr; + int i; + + printf("Image Type : Xilinx Zynq Boot Image support\n"); + printf("Image Offset : 0x%08x\n", le32_to_cpu(zynqhdr->image_offset)); + printf("Image Size : %lu bytes (%lu bytes packed)\n", + (unsigned long)le32_to_cpu(zynqhdr->image_size), + (unsigned long)le32_to_cpu(zynqhdr->image_stored_size)); + printf("Image Load : 0x%08x\n", le32_to_cpu(zynqhdr->image_load)); + printf("Checksum : 0x%08x\n", le32_to_cpu(zynqhdr->checksum)); + + for (i = 0; i < HEADER_INTERRUPT_VECTORS; i++) { + if (zynqhdr->interrupt_vectors[i] == HEADER_INTERRUPT_DEFAULT) + continue; + + printf("Modified Interrupt Vector Address [%d]: 0x%08x\n", i, + le32_to_cpu(zynqhdr->interrupt_vectors[i])); + } + + for (i = 0; i < HEADER_REGINITS; i++) { + if (zynqhdr->register_init[i].address == HEADER_REGINIT_NULL) + break; + + if (i == 0) + printf("Custom Register Initialization:\n"); + + printf(" @ 0x%08x -> 0x%08x\n", + le32_to_cpu(zynqhdr->register_init[i].address), + le32_to_cpu(zynqhdr->register_init[i].data)); + } +} + +static int zynqmpimage_check_params(struct image_tool_params *params) +{ + if (!params) + return 0; + + if (params->addr != 0x0) { + fprintf(stderr, "Error: Load Address cannot be specified.\n"); + return -1; + } + + /* + * If the entry point is specified ensure it is 64 byte aligned. + */ + if (params->eflag && (params->ep % 64 != 0)) { + fprintf(stderr, + "Error: Entry Point must be aligned to a 64-byte boundary.\n"); + return -1; + } + + return !(params->lflag || params->dflag); +} + +static int zynqmpimage_check_image_types(uint8_t type) +{ + if (type == IH_TYPE_ZYNQMPIMAGE) + return EXIT_SUCCESS; + return EXIT_FAILURE; +} + +static void zynqmpimage_set_header(void *ptr, struct stat *sbuf, int ifd, + struct image_tool_params *params) +{ + struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr; + zynqmpimage_default_header(zynqhdr); + + /* place image directly after header */ + zynqhdr->image_offset = + cpu_to_le32((uint32_t)sizeof(struct zynqmp_header)); + zynqhdr->image_size = cpu_to_le32(params->file_size - + sizeof(struct zynqmp_header)); + zynqhdr->image_stored_size = zynqhdr->image_size; + zynqhdr->image_load = 0xfffc0000; + if (params->eflag) + zynqhdr->image_load = cpu_to_le32((uint32_t)params->ep); + + zynqhdr->checksum = zynqmpimage_checksum(zynqhdr); +} + +U_BOOT_IMAGE_TYPE( + zynqmpimage, + "Xilinx ZynqMP Boot Image support", + sizeof(struct zynqmp_header), + (void *)&zynqmpimage_header, + zynqmpimage_check_params, + zynqmpimage_verify_header, + zynqmpimage_print_header, + zynqmpimage_set_header, + NULL, + zynqmpimage_check_image_types, + NULL, + NULL +); -- cgit v1.2.3 From dcdc1f6a9bd8abaa41b5eacd9310787cf96f4c4e Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Tue, 19 Apr 2016 22:43:39 +0200 Subject: tools/env: pass key as argument to env_aes_cbc_crypt Signed-off-by: Andreas Fenkart --- tools/env/fw_env.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 06cf63daa4e..0c448079cc3 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -106,7 +106,7 @@ static struct environment environment = { .flag_scheme = FLAG_NONE, }; -static int env_aes_cbc_crypt(char *data, const int enc); +static int env_aes_cbc_crypt(char *data, const int enc, uint8_t *key); static int HaveRedundEnv = 0; @@ -304,7 +304,8 @@ int fw_env_close(void) { int ret; if (common_args.aes_flag) { - ret = env_aes_cbc_crypt(environment.data, 1); + ret = env_aes_cbc_crypt(environment.data, 1, + common_args.aes_key); if (ret) { fprintf(stderr, "Error: can't encrypt env for flash\n"); @@ -949,7 +950,7 @@ static int flash_flag_obsolete (int dev, int fd, off_t offset) } /* Encrypt or decrypt the environment before writing or reading it. */ -static int env_aes_cbc_crypt(char *payload, const int enc) +static int env_aes_cbc_crypt(char *payload, const int enc, uint8_t *key) { uint8_t *data = (uint8_t *)payload; const int len = getenvsize(); @@ -957,7 +958,7 @@ static int env_aes_cbc_crypt(char *payload, const int enc) uint32_t aes_blocks; /* First we expand the key. */ - aes_expand_key(common_args.aes_key, key_exp); + aes_expand_key(key, key_exp); /* Calculate the number of AES blocks to encrypt. */ aes_blocks = DIV_ROUND_UP(len, AES_KEY_LENGTH); @@ -1186,7 +1187,8 @@ int fw_env_open(void) crc0 = crc32 (0, (uint8_t *) environment.data, ENV_SIZE); if (common_args.aes_flag) { - ret = env_aes_cbc_crypt(environment.data, 0); + ret = env_aes_cbc_crypt(environment.data, 0, + common_args.aes_key); if (ret) return ret; } @@ -1243,7 +1245,8 @@ int fw_env_open(void) crc1 = crc32 (0, (uint8_t *) redundant->data, ENV_SIZE); if (common_args.aes_flag) { - ret = env_aes_cbc_crypt(redundant->data, 0); + ret = env_aes_cbc_crypt(redundant->data, 0, + common_args.aes_key); if (ret) return ret; } -- cgit v1.2.3 From c3a23e8b5f7c13d9de389d25d756a7da64bc5144 Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Tue, 19 Apr 2016 22:43:40 +0200 Subject: tools/env: remove 'extern' from function prototype in fw_env.h checkpatch complains about in succeding patch. Prefer to fix all declarations in a dedicated patch. Signed-off-by: Andreas Fenkart --- tools/env/fw_env.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/env/fw_env.h b/tools/env/fw_env.h index 57149e733ba..7345922911f 100644 --- a/tools/env/fw_env.h +++ b/tools/env/fw_env.h @@ -78,12 +78,12 @@ extern struct setenv_args setenv_args; int parse_aes_key(char *key, uint8_t *bin_key); -extern int fw_printenv(int argc, char *argv[]); -extern char *fw_getenv (char *name); -extern int fw_setenv (int argc, char *argv[]); -extern int fw_parse_script(char *fname); -extern int fw_env_open(void); -extern int fw_env_write(char *name, char *value); -extern int fw_env_close(void); +int fw_printenv(int argc, char *argv[]); +char *fw_getenv(char *name); +int fw_setenv(int argc, char *argv[]); +int fw_parse_script(char *fname); +int fw_env_open(void); +int fw_env_write(char *name, char *value); +int fw_env_close(void); -extern unsigned long crc32 (unsigned long, const unsigned char *, unsigned); +unsigned long crc32(unsigned long, const unsigned char *, unsigned); -- cgit v1.2.3 From cedb341e7f44f4686c8c0afb149a9f7940be110a Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Tue, 19 Apr 2016 22:43:41 +0200 Subject: tools/env: fw_printenv pass value_only as argument Signed-off-by: Andreas Fenkart --- tools/env/fw_env.c | 6 +++--- tools/env/fw_env.h | 4 ++-- tools/env/fw_env_main.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 0c448079cc3..aa394858a08 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -239,7 +239,7 @@ int parse_aes_key(char *key, uint8_t *bin_key) * Print the current definition of one, or more, or all * environment variables */ -int fw_printenv (int argc, char *argv[]) +int fw_printenv(int argc, char *argv[], int value_only) { char *env, *nxt; int i, rc = 0; @@ -262,7 +262,7 @@ int fw_printenv (int argc, char *argv[]) return 0; } - if (printenv_args.name_suppress && argc != 1) { + if (value_only && argc != 1) { fprintf(stderr, "## Error: `-n' option requires exactly one argument\n"); return -1; @@ -283,7 +283,7 @@ int fw_printenv (int argc, char *argv[]) } val = envmatch (name, env); if (val) { - if (!printenv_args.name_suppress) { + if (!value_only) { fputs (name, stdout); putc ('=', stdout); } diff --git a/tools/env/fw_env.h b/tools/env/fw_env.h index 7345922911f..d4daeeafd97 100644 --- a/tools/env/fw_env.h +++ b/tools/env/fw_env.h @@ -67,7 +67,7 @@ struct common_args { extern struct common_args common_args; struct printenv_args { - int name_suppress; + int value_only; }; extern struct printenv_args printenv_args; @@ -78,7 +78,7 @@ extern struct setenv_args setenv_args; int parse_aes_key(char *key, uint8_t *bin_key); -int fw_printenv(int argc, char *argv[]); +int fw_printenv(int argc, char *argv[], int value_only); char *fw_getenv(char *name); int fw_setenv(int argc, char *argv[]); int fw_parse_script(char *fname); diff --git a/tools/env/fw_env_main.c b/tools/env/fw_env_main.c index 3706d8f1a61..2a45a0de287 100644 --- a/tools/env/fw_env_main.c +++ b/tools/env/fw_env_main.c @@ -151,7 +151,7 @@ int parse_printenv_args(int argc, char *argv[]) EOF) { switch (c) { case 'n': - printenv_args.name_suppress = 1; + printenv_args.value_only = 1; break; case 'a': case 'c': @@ -240,7 +240,7 @@ int main(int argc, char *argv[]) } if (do_printenv) { - if (fw_printenv(argc, argv) != 0) + if (fw_printenv(argc, argv, printenv_args.value_only)) retval = EXIT_FAILURE; } else { if (!setenv_args.script_file) { -- cgit v1.2.3 From f71cee4bfc9a8f9be40a49ec2da84f4344e398fc Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Tue, 19 Apr 2016 22:43:42 +0200 Subject: tools/env: compute size of usable area only once for double buffering to work, redundant buffers must have equal size Signed-off-by: Andreas Fenkart --- tools/env/fw_env.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index aa394858a08..1654ac0e46b 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -75,7 +75,8 @@ static int dev_current; #define CUR_ENVSIZE ENVSIZE(dev_current) -#define ENV_SIZE getenvsize() +static unsigned long usable_envsize; +#define ENV_SIZE usable_envsize struct env_image_single { uint32_t crc; /* CRC32 over data bytes */ @@ -124,18 +125,6 @@ static int parse_config (void); #if defined(CONFIG_FILE) static int get_config (char *); #endif -static inline ulong getenvsize (void) -{ - ulong rc = CUR_ENVSIZE - sizeof(uint32_t); - - if (HaveRedundEnv) - rc -= sizeof (char); - - if (common_args.aes_flag) - rc &= ~(AES_KEY_LENGTH - 1); - - return rc; -} static char *skip_chars(char *s) { @@ -953,7 +942,7 @@ static int flash_flag_obsolete (int dev, int fd, off_t offset) static int env_aes_cbc_crypt(char *payload, const int enc, uint8_t *key) { uint8_t *data = (uint8_t *)payload; - const int len = getenvsize(); + const int len = usable_envsize; uint8_t key_exp[AES_EXPAND_KEY_LENGTH]; uint32_t aes_blocks; @@ -1382,6 +1371,21 @@ static int parse_config () DEVNAME (1), strerror (errno)); return -1; } + + if (HaveRedundEnv && ENVSIZE(0) != ENVSIZE(1)) { + ENVSIZE(0) = ENVSIZE(1) = min(ENVSIZE(0), ENVSIZE(1)); + fprintf(stderr, + "Redundant environments have inequal size, set to 0x%08lx\n", + ENVSIZE(1)); + } + + usable_envsize = CUR_ENVSIZE - sizeof(uint32_t); + if (HaveRedundEnv) + usable_envsize -= sizeof(char); + + if (common_args.aes_flag) + usable_envsize &= ~(AES_KEY_LENGTH - 1); + return 0; } -- cgit v1.2.3 From 9217d93bc45668815ebaab0ad9280ace166b7348 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 14 May 2016 14:02:59 -0600 Subject: rockchip: Check image name for the rksd image We need a correct name (rk3288, rk3036) so check this to avoid a crash later. Signed-off-by: Simon Glass --- tools/rkimage.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/rkimage.c b/tools/rkimage.c index f9fdcfa712f..ef31cb69444 100644 --- a/tools/rkimage.c +++ b/tools/rkimage.c @@ -13,11 +13,6 @@ 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) { @@ -56,7 +51,7 @@ U_BOOT_IMAGE_TYPE( "Rockchip Boot Image support", 4, &header, - rkimage_check_params, + rkcommon_check_params, rkimage_verify_header, rkimage_print_header, rkimage_set_header, -- cgit v1.2.3 From 81974f4479d19c441c4a089aedd238c251626b3e Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Tue, 5 Apr 2016 23:13:42 +0200 Subject: tools/env: no global variable sharing between application and library Signed-off-by: Andreas Fenkart --- tools/env/fw_env.c | 50 +++++++++++++++++++++++-------------------------- tools/env/fw_env.h | 25 +++++++------------------ tools/env/fw_env_main.c | 28 +++++++++++++++++---------- 3 files changed, 48 insertions(+), 55 deletions(-) (limited to 'tools') diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 1654ac0e46b..52e0bec0897 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -35,10 +35,6 @@ #include "fw_env.h" -struct common_args common_args; -struct printenv_args printenv_args; -struct setenv_args setenv_args; - #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) #define min(x, y) ({ \ @@ -120,7 +116,7 @@ static unsigned char obsolete_flag = 0; static int flash_io (int mode); static char *envmatch (char * s1, char * s2); -static int parse_config (void); +static int parse_config(struct env_opts *opts); #if defined(CONFIG_FILE) static int get_config (char *); @@ -228,12 +224,12 @@ int parse_aes_key(char *key, uint8_t *bin_key) * Print the current definition of one, or more, or all * environment variables */ -int fw_printenv(int argc, char *argv[], int value_only) +int fw_printenv(int argc, char *argv[], int value_only, struct env_opts *opts) { char *env, *nxt; int i, rc = 0; - if (fw_env_open()) + if (fw_env_open(opts)) return -1; if (argc == 0) { /* Print all env variables */ @@ -289,12 +285,13 @@ int fw_printenv(int argc, char *argv[], int value_only) return rc; } -int fw_env_close(void) +int fw_env_close(struct env_opts *opts) { int ret; - if (common_args.aes_flag) { + + if (opts->aes_flag) { ret = env_aes_cbc_crypt(environment.data, 1, - common_args.aes_key); + opts->aes_key); if (ret) { fprintf(stderr, "Error: can't encrypt env for flash\n"); @@ -447,7 +444,7 @@ int fw_env_write(char *name, char *value) * modified or deleted * */ -int fw_setenv(int argc, char *argv[]) +int fw_setenv(int argc, char *argv[], struct env_opts *opts) { int i; size_t len; @@ -461,7 +458,7 @@ int fw_setenv(int argc, char *argv[]) return -1; } - if (fw_env_open()) { + if (fw_env_open(opts)) { fprintf(stderr, "Error: environment not initialized\n"); return -1; } @@ -497,7 +494,7 @@ int fw_setenv(int argc, char *argv[]) free(value); - return fw_env_close(); + return fw_env_close(opts); } /* @@ -517,7 +514,7 @@ int fw_setenv(int argc, char *argv[]) * 0 - OK * -1 - Error */ -int fw_parse_script(char *fname) +int fw_parse_script(char *fname, struct env_opts *opts) { FILE *fp; char dump[1024]; /* Maximum line length in the file */ @@ -527,7 +524,7 @@ int fw_parse_script(char *fname) int len; int ret = 0; - if (fw_env_open()) { + if (fw_env_open(opts)) { fprintf(stderr, "Error: environment not initialized\n"); return -1; } @@ -615,10 +612,9 @@ int fw_parse_script(char *fname) if (strcmp(fname, "-") != 0) fclose(fp); - ret |= fw_env_close(); + ret |= fw_env_close(opts); return ret; - } /* @@ -1128,7 +1124,7 @@ static char *envmatch (char * s1, char * s2) /* * Prevent confusion if running from erased flash memory */ -int fw_env_open(void) +int fw_env_open(struct env_opts *opts) { int crc0, crc0_ok; unsigned char flag0; @@ -1143,7 +1139,7 @@ int fw_env_open(void) struct env_image_single *single; struct env_image_redundant *redundant; - if (parse_config ()) /* should fill envdevices */ + if (parse_config(opts)) /* should fill envdevices */ return -1; addr0 = calloc(1, CUR_ENVSIZE); @@ -1175,9 +1171,9 @@ int fw_env_open(void) crc0 = crc32 (0, (uint8_t *) environment.data, ENV_SIZE); - if (common_args.aes_flag) { + if (opts->aes_flag) { ret = env_aes_cbc_crypt(environment.data, 0, - common_args.aes_key); + opts->aes_key); if (ret) return ret; } @@ -1233,9 +1229,9 @@ int fw_env_open(void) crc1 = crc32 (0, (uint8_t *) redundant->data, ENV_SIZE); - if (common_args.aes_flag) { + if (opts->aes_flag) { ret = env_aes_cbc_crypt(redundant->data, 0, - common_args.aes_key); + opts->aes_key); if (ret) return ret; } @@ -1312,7 +1308,7 @@ int fw_env_open(void) } -static int parse_config () +static int parse_config(struct env_opts *opts) { struct stat st; @@ -1321,9 +1317,9 @@ static int parse_config () common_args.config_file = CONFIG_FILE; /* Fills in DEVNAME(), ENVSIZE(), DEVESIZE(). Or don't. */ - if (get_config(common_args.config_file)) { + if (get_config(opts->config_file)) { fprintf(stderr, "Cannot parse config file '%s': %m\n", - common_args.config_file); + opts->config_file); return -1; } #else @@ -1383,7 +1379,7 @@ static int parse_config () if (HaveRedundEnv) usable_envsize -= sizeof(char); - if (common_args.aes_flag) + if (opts->aes_flag) usable_envsize &= ~(AES_KEY_LENGTH - 1); return 0; diff --git a/tools/env/fw_env.h b/tools/env/fw_env.h index d4daeeafd97..dac964d933f 100644 --- a/tools/env/fw_env.h +++ b/tools/env/fw_env.h @@ -57,33 +57,22 @@ "bootm" #endif -struct common_args { +struct env_opts { #ifdef CONFIG_FILE char *config_file; #endif - uint8_t aes_key[AES_KEY_LENGTH]; int aes_flag; /* Is AES encryption used? */ + uint8_t aes_key[AES_KEY_LENGTH]; }; -extern struct common_args common_args; - -struct printenv_args { - int value_only; -}; -extern struct printenv_args printenv_args; - -struct setenv_args { - char *script_file; -}; -extern struct setenv_args setenv_args; int parse_aes_key(char *key, uint8_t *bin_key); -int fw_printenv(int argc, char *argv[], int value_only); +int fw_printenv(int argc, char *argv[], int value_only, struct env_opts *opts); char *fw_getenv(char *name); -int fw_setenv(int argc, char *argv[]); -int fw_parse_script(char *fname); -int fw_env_open(void); +int fw_setenv(int argc, char *argv[], struct env_opts *opts); +int fw_parse_script(char *fname, struct env_opts *opts); +int fw_env_open(struct env_opts *opts); int fw_env_write(char *name, char *value); -int fw_env_close(void); +int fw_env_close(struct env_opts *opts); unsigned long crc32(unsigned long, const unsigned char *, unsigned); diff --git a/tools/env/fw_env_main.c b/tools/env/fw_env_main.c index 2a45a0de287..7a17b28f40b 100644 --- a/tools/env/fw_env_main.c +++ b/tools/env/fw_env_main.c @@ -49,6 +49,14 @@ static struct option long_options[] = { {NULL, 0, NULL, 0} }; +static struct env_opts env_opts; + +/* setenv options */ +static int noheader; + +/* getenv options */ +static char *script_file; + void usage_printenv(void) { @@ -108,22 +116,22 @@ static void parse_common_args(int argc, char *argv[]) int c; #ifdef CONFIG_FILE - common_args.config_file = CONFIG_FILE; + env_opts.config_file = CONFIG_FILE; #endif while ((c = getopt_long(argc, argv, ":a:c:h", long_options, NULL)) != EOF) { switch (c) { case 'a': - if (parse_aes_key(optarg, common_args.aes_key)) { + if (parse_aes_key(optarg, env_opts.aes_key)) { fprintf(stderr, "AES key parse error\n"); exit(EXIT_FAILURE); } - common_args.aes_flag = 1; + env_opts.aes_flag = 1; break; #ifdef CONFIG_FILE case 'c': - common_args.config_file = optarg; + env_opts.config_file = optarg; break; #endif case 'h': @@ -151,7 +159,7 @@ int parse_printenv_args(int argc, char *argv[]) EOF) { switch (c) { case 'n': - printenv_args.value_only = 1; + noheader = 1; break; case 'a': case 'c': @@ -177,7 +185,7 @@ int parse_setenv_args(int argc, char *argv[]) EOF) { switch (c) { case 's': - setenv_args.script_file = optarg; + script_file = optarg; break; case 'a': case 'c': @@ -240,14 +248,14 @@ int main(int argc, char *argv[]) } if (do_printenv) { - if (fw_printenv(argc, argv, printenv_args.value_only)) + if (fw_printenv(argc, argv, noheader, &env_opts) != 0) retval = EXIT_FAILURE; } else { - if (!setenv_args.script_file) { - if (fw_setenv(argc, argv) != 0) + if (!script_file) { + if (fw_setenv(argc, argv, &env_opts) != 0) retval = EXIT_FAILURE; } else { - if (fw_parse_script(setenv_args.script_file) != 0) + if (fw_parse_script(script_file, &env_opts) != 0) retval = EXIT_FAILURE; } } -- cgit v1.2.3 From d339df522beb6d9268231069fd9e1d3e73af49ed Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sun, 22 May 2016 15:16:47 +0900 Subject: tools/genboardscfg.py: remove bogus import subprocess Since f6c8f38ec601 ("tools/genboardscfg.py: improve performance more with Kconfiglib"), this tool does not use the subprocess module. Signed-off-by: Masahiro Yamada --- tools/genboardscfg.py | 1 - 1 file changed, 1 deletion(-) (limited to 'tools') diff --git a/tools/genboardscfg.py b/tools/genboardscfg.py index 23c956bb8ec..c2efad55ab4 100755 --- a/tools/genboardscfg.py +++ b/tools/genboardscfg.py @@ -21,7 +21,6 @@ import glob import multiprocessing import optparse import os -import subprocess import sys import tempfile import time -- cgit v1.2.3 From 87c2f76f3fae11bf559996505e23b37d03f4c5dc Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sun, 22 May 2016 05:46:05 -0400 Subject: tools: Add entry for generated tools/bin2header to tools/.gitignore Signed-off-by: Robert P. J. Day --- tools/.gitignore | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/.gitignore b/tools/.gitignore index ff076803085..cb1e722d457 100644 --- a/tools/.gitignore +++ b/tools/.gitignore @@ -1,4 +1,5 @@ /atmel_pmecc_params +/bin2header /bmp_logo /envcrc /fdtgrep -- cgit v1.2.3 From 14070e69ad6d01abf65c06150dc9302bca1b7973 Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Tue, 31 May 2016 09:21:56 +0200 Subject: tools/env: allow to pass NULL for environment options If users of the library are happy with the default, e.g. config file name. They can pass NULL as the opts pointer. This simplifies the transition of existing library users. FIXES a compile error. since common_args has been removed by a previous patch Signed-off-by: Andreas Fenkart --- tools/env/fw_env.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 52e0bec0897..692abda7318 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -35,6 +35,12 @@ #include "fw_env.h" +struct env_opts default_opts = { +#ifdef CONFIG_FILE + .config_file = CONFIG_FILE +#endif +}; + #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) #define min(x, y) ({ \ @@ -229,6 +235,9 @@ int fw_printenv(int argc, char *argv[], int value_only, struct env_opts *opts) char *env, *nxt; int i, rc = 0; + if (!opts) + opts = &default_opts; + if (fw_env_open(opts)) return -1; @@ -289,6 +298,9 @@ int fw_env_close(struct env_opts *opts) { int ret; + if (!opts) + opts = &default_opts; + if (opts->aes_flag) { ret = env_aes_cbc_crypt(environment.data, 1, opts->aes_key); @@ -452,6 +464,9 @@ int fw_setenv(int argc, char *argv[], struct env_opts *opts) char *value = NULL; int valc; + if (!opts) + opts = &default_opts; + if (argc < 1) { fprintf(stderr, "## Error: variable name missing\n"); errno = EINVAL; @@ -524,6 +539,9 @@ int fw_parse_script(char *fname, struct env_opts *opts) int len; int ret = 0; + if (!opts) + opts = &default_opts; + if (fw_env_open(opts)) { fprintf(stderr, "Error: environment not initialized\n"); return -1; @@ -1139,6 +1157,9 @@ int fw_env_open(struct env_opts *opts) struct env_image_single *single; struct env_image_redundant *redundant; + if (!opts) + opts = &default_opts; + if (parse_config(opts)) /* should fill envdevices */ return -1; @@ -1312,10 +1333,10 @@ static int parse_config(struct env_opts *opts) { struct stat st; -#if defined(CONFIG_FILE) - if (!common_args.config_file) - common_args.config_file = CONFIG_FILE; + if (!opts) + opts = &default_opts; +#if defined(CONFIG_FILE) /* Fills in DEVNAME(), ENVSIZE(), DEVESIZE(). Or don't. */ if (get_config(opts->config_file)) { fprintf(stderr, "Cannot parse config file '%s': %m\n", -- cgit v1.2.3 From ea7d1eec66898b233ac49f8a60391b96afa25477 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Mon, 30 May 2016 13:57:53 -0500 Subject: mtd: nand: Remove docg4 driver and palmtreo680 flashing tool Commit ad4f54ea86b ("arm: Remove palmtreo680 board") removed the only user of the docg4 driver and the palmtreo680 image flashing tool. This patch removes them. Signed-off-by: Scott Wood Cc: Mike Dunn Cc: Simon Glass --- tools/palmtreo680/flash_u-boot.c | 177 --------------------------------------- 1 file changed, 177 deletions(-) delete mode 100644 tools/palmtreo680/flash_u-boot.c (limited to 'tools') diff --git a/tools/palmtreo680/flash_u-boot.c b/tools/palmtreo680/flash_u-boot.c deleted file mode 100644 index 832d3fef7b8..00000000000 --- a/tools/palmtreo680/flash_u-boot.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2013 Mike Dunn - * - * This file is released under the terms of GPL v2 and any later version. - * See the file COPYING in the root directory of the source tree for details. - * - * - * This is a userspace Linux utility that, when run on the Treo 680, will - * program u-boot to flash. The docg4 driver *must* be loaded with the - * reliable_mode and ignore_badblocks parameters enabled: - * - * modprobe docg4 ignore_badblocks=1 reliable_mode=1 - * - * This utility writes the concatenated spl + u-boot image to the start of the - * mtd device in the format expected by the IPL/SPL. The image file and mtd - * device node are passed to the utility as arguments. The blocks must have - * been erased beforehand. - * - * When you compile this, note that it links to libmtd from mtd-utils, so ensure - * that your include and lib paths include this. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "libmtd.h" - -#define RELIABLE_BLOCKSIZE 0x10000 /* block capacity in reliable mode */ -#define STANDARD_BLOCKSIZE 0x40000 /* block capacity in normal mode */ -#define PAGESIZE 512 -#define PAGES_PER_BLOCK 512 -#define OOBSIZE 7 /* available to user (16 total) */ - -uint8_t ff_oob[OOBSIZE] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - -/* this is the magic number the IPL looks for (ASCII "BIPO") */ -uint8_t page0_oob[OOBSIZE] = {'B', 'I', 'P', 'O', 0xff, 0xff, 0xff}; - -int main(int argc, char * const argv[]) -{ - int devfd, datafd, num_blocks, block; - off_t file_size; - libmtd_t mtd_desc; - struct mtd_dev_info devinfo; - uint8_t *blockbuf; - char response[8]; - - if (argc != 3) { - printf("usage: %s \n", argv[0]); - return -EINVAL; - } - - mtd_desc = libmtd_open(); - if (mtd_desc == NULL) { - int errsv = errno; - fprintf(stderr, "can't initialize libmtd\n"); - return -errsv; - } - - /* open the spl image file and mtd device */ - datafd = open(argv[1], O_RDONLY); - if (datafd == -1) { - int errsv = errno; - perror(argv[1]); - return -errsv; - } - devfd = open(argv[2], O_WRONLY); - if (devfd == -1) { - int errsv = errno; - perror(argv[2]); - return -errsv; - } - if (mtd_get_dev_info(mtd_desc, argv[2], &devinfo) < 0) { - int errsv = errno; - perror(argv[2]); - return -errsv; - } - - /* determine the number of blocks needed by the image */ - file_size = lseek(datafd, 0, SEEK_END); - if (file_size == (off_t)-1) { - int errsv = errno; - perror("lseek"); - return -errsv; - } - num_blocks = (file_size + RELIABLE_BLOCKSIZE - 1) / RELIABLE_BLOCKSIZE; - file_size = lseek(datafd, 0, SEEK_SET); - if (file_size == (off_t)-1) { - int errsv = errno; - perror("lseek"); - return -errsv; - } - printf("The mtd partition contains %d blocks\n", devinfo.eb_cnt); - printf("U-Boot will occupy %d blocks\n", num_blocks); - if (num_blocks > devinfo.eb_cnt) { - fprintf(stderr, "Insufficient blocks on partition\n"); - return -EINVAL; - } - - printf("IMPORTANT: These blocks must be in an erased state!\n"); - printf("Do you want to proceed?\n"); - scanf("%s", response); - if ((response[0] != 'y') && (response[0] != 'Y')) { - printf("Exiting\n"); - close(devfd); - close(datafd); - return 0; - } - - blockbuf = calloc(RELIABLE_BLOCKSIZE, 1); - if (blockbuf == NULL) { - int errsv = errno; - perror("calloc"); - return -errsv; - } - - for (block = 0; block < num_blocks; block++) { - int ofs, page; - uint8_t *pagebuf = blockbuf, *buf = blockbuf; - uint8_t *oobbuf = page0_oob; /* magic num in oob of 1st page */ - size_t len = RELIABLE_BLOCKSIZE; - int ret; - - /* read data for one block from file */ - while (len) { - ssize_t read_ret = read(datafd, buf, len); - if (read_ret == -1) { - int errsv = errno; - if (errno == EINTR) - continue; - perror("read"); - return -errsv; - } else if (read_ret == 0) { - break; /* EOF */ - } - len -= read_ret; - buf += read_ret; - } - - printf("Block %d: writing\r", block + 1); - fflush(stdout); - - for (page = 0, ofs = 0; - page < PAGES_PER_BLOCK; - page++, ofs += PAGESIZE) { - if (page & 0x04) /* Odd-numbered 2k page */ - continue; /* skipped in reliable mode */ - - ret = mtd_write(mtd_desc, &devinfo, devfd, block, ofs, - pagebuf, PAGESIZE, oobbuf, OOBSIZE, - MTD_OPS_PLACE_OOB); - if (ret) { - fprintf(stderr, - "\nmtd_write returned %d on block %d, ofs %x\n", - ret, block + 1, ofs); - return -EIO; - } - oobbuf = ff_oob; /* oob for subsequent pages */ - - if (page & 0x01) /* odd-numbered subpage */ - pagebuf += PAGESIZE; - } - } - - printf("\nDone\n"); - - close(devfd); - close(datafd); - free(blockbuf); - return 0; -} -- cgit v1.2.3