diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/Makefile | 2 | ||||
| -rw-r--r-- | tools/mkimage.c | 15 | ||||
| -rw-r--r-- | tools/mkimage.h | 3 | ||||
| -rw-r--r-- | tools/patman/series.py | 8 | ||||
| -rw-r--r-- | tools/pblimage.c | 331 | ||||
| -rw-r--r-- | tools/pblimage.h | 36 | 
6 files changed, 391 insertions, 4 deletions
| diff --git a/tools/Makefile b/tools/Makefile index a7d1e18fe..c31437e6a 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -92,6 +92,7 @@ OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o  OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o  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 += omapimage.o  NOPED_OBJ_FILES-y += mkenvimage.o @@ -208,6 +209,7 @@ $(obj)mkimage$(SFX):	$(obj)aisimage.o \  			$(obj)image.o \  			$(obj)imximage.o \  			$(obj)kwbimage.o \ +			$(obj)pblimage.o \  			$(obj)md5.o \  			$(obj)mkimage.o \  			$(obj)os_support.o \ diff --git a/tools/mkimage.c b/tools/mkimage.c index eeb1b1066..e43b09f76 100644 --- a/tools/mkimage.c +++ b/tools/mkimage.c @@ -39,6 +39,7 @@ struct mkimage_params params = {  	.comp = IH_COMP_GZIP,  	.dtc = MKIMAGE_DEFAULT_DTC_OPTIONS,  	.imagename = "", +	.imagename2 = "",  };  /* @@ -150,6 +151,8 @@ main (int argc, char **argv)  	int retval = 0;  	struct image_type_params *tparams = NULL; +	/* Init Freescale PBL Boot image generation/list support */ +	init_pbl_image_type();  	/* Init Kirkwood Boot image generation/list support */  	init_kwb_image_type ();  	/* Init Freescale imx Boot image generation/list support */ @@ -250,6 +253,15 @@ main (int argc, char **argv)  					usage ();  				params.imagename = *++argv;  				goto NXTARG; +			case 'R': +				if (--argc <= 0) +					usage(); +				/* +				 * This entry is for the second configuration +				 * file, if only one is not enough. +				 */ +				params.imagename2 = *++argv; +				goto NXTARG;  			case 's':  				params.skipcpy = 1;  				break; @@ -440,6 +452,9 @@ NXTARG:		;  					break;  				}  			} +		} else if (params.type == IH_TYPE_PBLIMAGE) { +			/* PBL has special Image format, implements its' own */ +			pbl_load_uboot(ifd, ¶ms);  		} else {  			copy_file (ifd, params.datafile, 0);  		} diff --git a/tools/mkimage.h b/tools/mkimage.h index 5fe1a48cc..ea45f5c83 100644 --- a/tools/mkimage.h +++ b/tools/mkimage.h @@ -69,6 +69,7 @@ struct mkimage_params {  	unsigned int addr;  	unsigned int ep;  	char *imagename; +	char *imagename2;  	char *datafile;  	char *imagefile;  	char *cmdname; @@ -147,6 +148,8 @@ void mkimage_register (struct image_type_params *tparams);   *   * Supported image types init functions   */ +void pbl_load_uboot(int fd, struct mkimage_params *mparams); +void init_pbl_image_type(void);  void init_ais_image_type(void);  void init_kwb_image_type (void);  void init_imx_image_type (void); diff --git a/tools/patman/series.py b/tools/patman/series.py index 27528bf21..ce36b230a 100644 --- a/tools/patman/series.py +++ b/tools/patman/series.py @@ -145,18 +145,18 @@ class Series(dict):          Return:              The change log as a list of strings, one per line +            Changes in v2: +            - Jog the dial back closer to the widget +              Changes in v1:              - Fix the widget              - Jog the dial -            Changes in v2: -            - Jog the dial back closer to the widget -              etc.          """          final = []          need_blank = False -        for change in sorted(self.changes): +        for change in sorted(self.changes, reverse=True):              out = []              for this_commit, text in self.changes[change]:                  if commit and this_commit != commit: diff --git a/tools/pblimage.c b/tools/pblimage.c new file mode 100644 index 000000000..508a747a3 --- /dev/null +++ b/tools/pblimage.c @@ -0,0 +1,331 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#define _GNU_SOURCE + +#include "mkimage.h" +#include <image.h> +#include "pblimage.h" + +/* + * The PBL can load up to 64 bytes at a time, so we split the U-Boot + * image into 64 byte chunks. PBL needs a command for each piece, of + * the form "81xxxxxx", where "xxxxxx" is the offset. SYS_TEXT_BASE + * is 0xFFF80000 for PBL boot, and PBL only cares about low 24-bit, + * so it starts from 0x81F80000. + */ +static uint32_t next_pbl_cmd = 0x81F80000; +/* + * need to store all bytes in memory for calculating crc32, then write the + * bytes to image file for PBL boot. + */ +static unsigned char mem_buf[600000]; +static unsigned char *pmem_buf = mem_buf; +static int pbl_size; +static char *fname = "Unknown"; +static int lineno = -1; +static struct pbl_header pblimage_header; + +static union +{ +	char c[4]; +	unsigned char l; +} endian_test = { {'l', '?', '?', 'b'} }; + +#define ENDIANNESS ((char)endian_test.l) + +static void generate_pbl_cmd(void) +{ +	uint32_t val = next_pbl_cmd; +	next_pbl_cmd += 0x40; +	int i; + +	for (i = 3; i >= 0; i--) { +		*pmem_buf++ = (val >> (i * 8)) & 0xff; +		pbl_size++; +	} +} + +static void pbl_fget(size_t size, FILE *stream) +{ +	unsigned char c; +	int c_temp; + +	while (size && (c_temp = fgetc(stream)) != EOF) { +		c = (unsigned char)c_temp; +		*pmem_buf++ = c; +		pbl_size++; +		size--; +	} +} + +/* load split u-boot with PBI command 81xxxxxx. */ +static void load_uboot(FILE *fp_uboot) +{ +	while (next_pbl_cmd < 0x82000000) { +		generate_pbl_cmd(); +		pbl_fget(64, fp_uboot); +	} +} + +static void check_get_hexval(char *token) +{ +	uint32_t hexval; +	int i; + +	if (!sscanf(token, "%x", &hexval)) { +		printf("Error:%s[%d] - Invalid hex data(%s)\n", fname, +			lineno, token); +		exit(EXIT_FAILURE); +	} +	for (i = 3; i >= 0; i--) { +		*pmem_buf++ = (hexval >> (i * 8)) & 0xff; +		pbl_size++; +	} +} + +static void pbl_parser(char *name) +{ +	FILE *fd = NULL; +	char *line = NULL; +	char *token, *saveptr1, *saveptr2; +	size_t len = 0; + +	fname = name; +	fd = fopen(name, "r"); +	if (fd == NULL) { +		printf("Error:%s - Can't open\n", fname); +		exit(EXIT_FAILURE); +	} + +	while ((getline(&line, &len, fd)) > 0) { +		lineno++; +		token = strtok_r(line, "\r\n", &saveptr1); +		/* drop all lines with zero tokens (= empty lines) */ +		if (token == NULL) +			continue; +		for (line = token;; line = NULL) { +			token = strtok_r(line, " \t", &saveptr2); +			if (token == NULL) +				break; +			/* Drop all text starting with '#' as comments */ +			if (token[0] == '#') +				break; +			check_get_hexval(token); +		} +	} +	if (line) +		free(line); +	fclose(fd); +} + +static uint32_t crc_table[256]; + +static void make_crc_table(void) +{ +	uint32_t mask; +	int i, j; +	uint32_t poly; /* polynomial exclusive-or pattern */ + +	/* +	 * the polynomial used by PBL is 1 + x1 + x2 + x4 + x5 + x7 + x8 + x10 +	 * + x11 + x12 + x16 + x22 + x23 + x26 + x32. +	 */ +	poly = 0x04c11db7; + +	for (i = 0; i < 256; i++) { +		mask = i << 24; +		for (j = 0; j < 8; j++) { +			if (mask & 0x80000000) +				mask = (mask << 1) ^ poly; +			else +				mask <<= 1; +		} +		crc_table[i] = mask; +	} +} + +unsigned long pbl_crc32(unsigned long crc, const char *buf, uint32_t len) +{ +	uint32_t crc32_val = 0xffffffff; +	uint32_t xor = 0x0; +	int i; + +	make_crc_table(); + +	for (i = 0; i < len; i++) +		crc32_val = (crc32_val << 8) ^ +			crc_table[(crc32_val >> 24) ^ (*buf++ & 0xff)]; + +	crc32_val = crc32_val ^ xor; +	if (crc32_val < 0) { +		crc32_val += 0xffffffff; +		crc32_val += 1; +	} +	return crc32_val; +} + +static uint32_t reverse_byte(uint32_t val) +{ +	uint32_t temp; +	unsigned char *p1; +	int j; + +	temp = val; +	p1 = (unsigned char *)&temp; +	for (j = 3; j >= 0; j--) +		*p1++ = (val >> (j * 8)) & 0xff; +	return temp; +} + +/* write end command and crc command to memory. */ +static void add_end_cmd(void) +{ +	uint32_t pbl_end_cmd[4] = {0x09138000, 0x00000000, +		0x091380c0, 0x00000000}; +	uint32_t crc32_pbl; +	int i; +	unsigned char *p = (unsigned char *)&pbl_end_cmd; + +	if (ENDIANNESS == 'l') { +		for (i = 0; i < 4; i++) +			pbl_end_cmd[i] = reverse_byte(pbl_end_cmd[i]); +	} + +	for (i = 0; i < 16; i++) { +		*pmem_buf++ = *p++; +		pbl_size++; +	} + +	/* Add PBI CRC command. */ +	*pmem_buf++ = 0x08; +	*pmem_buf++ = 0x13; +	*pmem_buf++ = 0x80; +	*pmem_buf++ = 0x40; +	pbl_size += 4; + +	/* calculated CRC32 and write it to memory. */ +	crc32_pbl = pbl_crc32(0, (const char *)mem_buf, pbl_size); +	*pmem_buf++ = (crc32_pbl >> 24) & 0xff; +	*pmem_buf++ = (crc32_pbl >> 16) & 0xff; +	*pmem_buf++ = (crc32_pbl >> 8) & 0xff; +	*pmem_buf++ = (crc32_pbl) & 0xff; +	pbl_size += 4; + +	if ((pbl_size % 16) != 0) { +		for (i = 0; i < 8; i++) { +			*pmem_buf++ = 0x0; +			pbl_size++; +		} +	} +	if ((pbl_size % 16 != 0)) { +		printf("Error: Bad size of image file\n"); +		exit(EXIT_FAILURE); +	} +} + +void pbl_load_uboot(int ifd, struct mkimage_params *params) +{ +	FILE *fp_uboot; +	int size; + +	/* parse the rcw.cfg file. */ +	pbl_parser(params->imagename); + +	/* parse the pbi.cfg file. */ +	pbl_parser(params->imagename2); + +	fp_uboot = fopen(params->datafile, "r"); +	if (fp_uboot == NULL) { +		printf("Error: %s open failed\n", params->datafile); +		exit(EXIT_FAILURE); +	} + +	load_uboot(fp_uboot); +	add_end_cmd(); +	fclose(fp_uboot); +	lseek(ifd, 0, SEEK_SET); + +	size = pbl_size; +	if (write(ifd, (const void *)&mem_buf, size) != size) { +		fprintf(stderr, "Write error on %s: %s\n", +			params->imagefile, strerror(errno)); +		exit(EXIT_FAILURE); +	} +} + +static int pblimage_check_image_types(uint8_t type) +{ +	if (type == IH_TYPE_PBLIMAGE) +		return EXIT_SUCCESS; +	else +		return EXIT_FAILURE; +} + +static int pblimage_verify_header(unsigned char *ptr, int image_size, +			struct mkimage_params *params) +{ +	struct pbl_header *pbl_hdr = (struct pbl_header *) ptr; + +	/* Only a few checks can be done: search for magic numbers */ +	if (ENDIANNESS == 'l') { +		if (pbl_hdr->preamble != reverse_byte(RCW_PREAMBLE)) +			return -FDT_ERR_BADSTRUCTURE; + +		if (pbl_hdr->rcwheader != reverse_byte(RCW_HEADER)) +			return -FDT_ERR_BADSTRUCTURE; +	} else { +		if (pbl_hdr->preamble != RCW_PREAMBLE) +			return -FDT_ERR_BADSTRUCTURE; + +		if (pbl_hdr->rcwheader != RCW_HEADER) +			return -FDT_ERR_BADSTRUCTURE; +	} +	return 0; +} + +static void pblimage_print_header(const void *ptr) +{ +	printf("Image Type:   Freescale PBL Boot Image\n"); +} + +static void pblimage_set_header(void *ptr, struct stat *sbuf, int ifd, +				struct mkimage_params *params) +{ +	/*nothing need to do, pbl_load_uboot takes care of whole file. */ +} + +/* pblimage parameters */ +static struct image_type_params pblimage_params = { +	.name		= "Freescale PBL Boot Image support", +	.header_size	= sizeof(struct pbl_header), +	.hdr		= (void *)&pblimage_header, +	.check_image_type = pblimage_check_image_types, +	.verify_header	= pblimage_verify_header, +	.print_header	= pblimage_print_header, +	.set_header	= pblimage_set_header, +}; + +void init_pbl_image_type(void) +{ +	pbl_size = 0; +	mkimage_register(&pblimage_params); +} diff --git a/tools/pblimage.h b/tools/pblimage.h new file mode 100644 index 000000000..514a477ca --- /dev/null +++ b/tools/pblimage.h @@ -0,0 +1,36 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef PBLIMAGE_H +#define PBLIMAGE_H + +#define RCW_BYTES	64 +#define RCW_PREAMBLE	0xaa55aa55 +#define RCW_HEADER	0x010e0100 + +struct pbl_header { +	uint32_t preamble; +	uint32_t rcwheader; +	uint8_t rcw_data[RCW_BYTES]; +}; + +#endif /* PBLIMAGE_H */ |