[U-Boot] [PATCH] powerpc/CoreNet: add tool to support pbl image build.

Scott Wood scottwood at freescale.com
Tue Jun 5 02:32:36 CEST 2012


On 06/04/2012 03:57 AM, Shaohui Xie wrote:
> From: Shaohui Xie <b21989 at freescale.com>
> 
> Provides a tool to build boot Image for PBL(Pre boot loader) which is
> used on Freescale CoreNet SoCs, PBL can be used to load some instructions
> and/or data for pre-initialization. The default output image is u-boot.pbl,
> for more details please refer to doc/README.pblimage.
> 
> Signed-off-by: Shaohui Xie <b21989 at freescale.com>
> ---
> rebased to lasted tree.
> 
>  Makefile                                |    5 +
>  board/freescale/corenet_ds/config.mk    |   26 +++
>  board/freescale/corenet_ds/pblimage.cfg |   60 ++++++
>  common/image.c                          |    1 +
>  doc/README.pblimage                     |  140 +++++++++++++
>  include/image.h                         |    1 +
>  tools/Makefile                          |    2 +
>  tools/mkimage.c                         |    5 +
>  tools/mkimage.h                         |    2 +
>  tools/pblimage.c                        |  329 +++++++++++++++++++++++++++++++
>  tools/pblimage.h                        |   36 ++++
>  11 files changed, 607 insertions(+), 0 deletions(-)
>  create mode 100644 board/freescale/corenet_ds/config.mk
>  create mode 100644 board/freescale/corenet_ds/pblimage.cfg
>  create mode 100644 doc/README.pblimage
>  create mode 100644 tools/pblimage.c
>  create mode 100644 tools/pblimage.h
> 
> diff --git a/Makefile b/Makefile
> index 57ad45b..99f993a 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -416,6 +416,10 @@ $(obj)u-boot.kwb:       $(obj)u-boot.bin
>  		$(obj)tools/mkimage -n $(CONFIG_SYS_KWD_CONFIG) -T kwbimage \
>  		-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) -d $< $@
*>
> +$(obj)u-boot.pbl:       $(obj)u-boot.bin
> +		$(obj)tools/mkimage -n $(CONFIG_PBL_CONFIG) -T pblimage \
> +		-d $< $@
> +
>  $(obj)u-boot.sha1:	$(obj)u-boot.bin
>  		$(obj)tools/ubsha1 $(obj)u-boot.bin
>  
> @@ -773,6 +777,7 @@ clobber:	tidy
>  		$(obj)cscope.* $(obj)*.*~
>  	@rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL-y)
>  	@rm -f $(obj)u-boot.kwb
> +	@rm -f $(obj)u-boot.pbl
>  	@rm -f $(obj)u-boot.imx
>  	@rm -f $(obj)u-boot.ubl
>  	@rm -f $(obj)u-boot.ais
> diff --git a/board/freescale/corenet_ds/config.mk b/board/freescale/corenet_ds/config.mk
> new file mode 100644
> index 0000000..72464dc
> --- /dev/null
> +++ b/board/freescale/corenet_ds/config.mk
> @@ -0,0 +1,26 @@
> +#
> +# 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
> +#
> +
> +ifeq ($(CONFIG_RAMBOOT_PBL), y)
> +CONFIG_PBL_CONFIG = $(SRCTREE)/$(CONFIG_BOARDDIR)/pblimage.cfg
> +ALL-y += $(obj)u-boot.pbl
> +endif

Why is this specific to corenet_ds?

> diff --git a/board/freescale/corenet_ds/pblimage.cfg b/board/freescale/corenet_ds/pblimage.cfg
> new file mode 100644
> index 0000000..898fe6d
> --- /dev/null
> +++ b/board/freescale/corenet_ds/pblimage.cfg
> @@ -0,0 +1,60 @@
> +#
> +# Copyright 2012 Freescale Semiconductor, Inc.
> +# Written-by: Shaohui Xie<b21989 at freescale.com>
> +#
> +# 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., 51 Franklin Street, Fifth Floor, Boston,
> +# MA 02110-1301 USA
> +#
> +# Refer docs/README.pblimage for more details about how-to configure
> +# and create PBL boot image
> +#
> +
> +#PBL preamble and RCW header
> +aa55aa55 010e0100
> +#64 bytes RCW data for P4080, replace it when building image
> +#for P3041DS or P5020DS.
> +4c580000 00000000 18185218 0000cccc
> +40464000 3c3c2000 58000000 61000000
> +00000000 00000000 00000000 008b6000
> +00000000 00000000 00000000 00000000

Could you have the tool source this from a separate file, rather than
require the user to replace it manually?

Talk to Timur (when he gets back from vacation in a couple weeks) about
his RCW tool and how best to accept the output it produces.

> +#PBI commands
> +#Initialize CPC1
> +09010000 00200400
> +09138000 00000000
> +091380c0 00000100
> +09010100 00000000
> +09010104 fff0000b
> +09010f00 08000000
> +09010000 80000000
> +#Configure LAW for CPC1
> +09000d00 00000000
> +09000d04 fff00000
> +09000d08 81000013
> +09000010 00000000
> +09000014 ff000000
> +09000018 81000000
> +#Initialize eSPI controller
> +09110000 80000403
> +09110020 2d170008
> +09110024 00100008
> +09110028 00100008
> +0911002c 00100008
> +#Flush PBL data
> +09138000 00000000
> +091380c0 00000000

Why is eSPI in here?  Isn't this supposed to just generically write an
image into CPC SRAM?

> diff --git a/doc/README.pblimage b/doc/README.pblimage
> new file mode 100644
> index 0000000..73d90f1
> --- /dev/null
> +++ b/doc/README.pblimage
> @@ -0,0 +1,140 @@
> +------------------------------------------------------------------
> +Freescale PBL(pre-boot loader) Boot Image generation using mkimage
> +------------------------------------------------------------------
> +
> +This document describes the U-Boot feature as it
> +is implemented for the Freescale CoreNet SoC.
> +
> +The CoreNet SoC's can boot directly from eSPI FLASH, SD/MMC.
> +
> +for more details refer section 5 Pre-boot loader specifications.
> +
> +Building PBL Boot Image and boot steps
> +--------------------------------------
> +
> +1. Building PBL Boot Image.
> +   The default Image is u-boot.pbl. Before build the iamge, make sure
> +   rcw data in pblimage.cfg is suitable for the platform, if not, this
> +   need to be fixed in step 2.
> +
> +   For eSPI boot:
> +	To build the eSPI boot image for P4080DS:
> +	make P4080DS_SPIFLASH
> +
> +	To build the eSPI boot image for P3041DS:
> +	make P3041DS_SPIFLASH
> +
> +	To build the eSPI boot image for P5020DS:
> +	make P5020DS_SPIFLASH
> +
> +   For SD boot:
> +	To build the SD boot image for P4080DS:
> +	make P4080DS_SDCARD
> +
> +	To build the SD boot image for P3041DS:
> +	make P3041DS_SDCARD
> +
> +	To build the SD boot image for P5020DS:
> +	make P5020DS_SDCARD
> +
> +   For Nand boot(P4080DS does not have Nand chip):
> +	To build the PBL boot image for P3041DS:
> +	make P3041DS_NAND
> +
> +	To build the PBL boot image for P5020DS:
> +	make P5020DS_NAND


> +
> +
> +2. Command below provided a way to re-build the PBL boot image if the
> +configuration file needes to be modified while the u-boot.bin does not
> +need to be re-build.
> +
> +Command syntax:
> +--------------
> +./tools/mkimage -n <board specific configuration file> \
> +		-T pblimage -d <input_raw_binary> <output_pblboot_file>
> +
> +for ex.
> +./tools/mkimage -n ./board/freescale/corenet_ds/pblimage.cfg \
> +		-T pblimage -d u-boot.bin u-boot.pbl
> +
> +
> +3. pblimage support available with mkimage utility will generate Freescale PBL
> +boot image that can be flashed on the board eSPI flash, SD/MMC. Following steps
> +described how to boot from eSPI flash, SD/MMC.
> +
> +	1). Boot from eSPI flash
> +	Write u-boot.pbl to eSPI flash from offset 0x0.
> +	for ex in u-boot:
> +	=>tftp 100000 u-boot.pbl
> +	=>sf probe 0
> +	=>sf erase 0 100000
> +	=>sf write 100000 0 $filesize
> +	Change SW1[1:5] = off off on off on.
> +
> +	2). Boot from SD/MMC
> +	Write u-boot.pbl to SD/MMC from offset 0x1000.
> +	for ex in u-boot:
> +	=>tftp 100000 u-boot.pbl
> +	=>mmcinfo
> +	=>mmc write 100000 8 441
> +	Change SW1[1:5] = off off on on off.
> +
> +	3). Boot from Nand
> +	Write u-boot.pbl to Nand from offset 0x0, Note that in case of eLBC NAND
> +	flash, the address starts from the first good block.
> +	for ex in u-boot:
> +	=>tftp 100000 u-boot.pbl
> +	=>nand info
> +	=>nand erase 0 100000
> +	=>nand write 100000 0 $filesize
> +	Change SW1[1:5] = off on off off on
> +	Change SW7[1:4] = on off off on

How do you load the environment?  We should find a way, possibly using
SPL, to have the environment ready early.  We do not want to wait post
relocation for the full NAND/SD/SPI driver to load the environment.

> diff --git a/tools/mkimage.h b/tools/mkimage.h
> index 5fe1a48..a886305 100644
> --- a/tools/mkimage.h
> +++ b/tools/mkimage.h
> @@ -147,6 +147,8 @@ void mkimage_register (struct image_type_params *tparams);
>   *
>   * Supported image types init functions
>   */
> +void pbl_load_uboot(int, struct mkimage_params *);

Please provide names for parameters.

> +/*
> + * PBL can load 64 bytes each time in MAX, so the u-boot need to be splited into
> + * pieces of 64 bytes, PBL needs a command for each piece, the command looks
> + * like 81xxxxxx, the "xxxxxx" is offset, it starts from F80000 in our case.
> + */

Better wording:

  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.

Why are we hardcoding 0xf80000?  Where does it come from?

> +static unsigned int uboot_label = 0x81F80000;

I'm not sure that label is the right word here.  Maybe "next_pbl_cmd"?

> +/*
> + * 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];

600000 is arbitrary.  Do you have any checking if the image size exceeds
this?  Can you dynamically allocate the buffer instead?

> +static unsigned char *pmem_buf = mem_buf;
> +static int mem_byte_cnt;

s/mem_byte_cnt/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'} };

Please fix whitespace.

> +#define ENDIANNESS ((char)endian_test.l)
> +
> +static void generate_pbl_cmd(void)
> +{
> +	unsigned int val = uboot_label;

s/unsigned int/uint32_t/

> +	uboot_label += 0x40;
> +	int i;
> +
> +	for (i = 3; i >= 0; i--) {
> +		*pmem_buf++ = (val >> (i * 8)) & 0xff;
> +		mem_byte_cnt++;
> +	}
> +}
> +
> +static void pbl_fget(size_t size, FILE *stream)
> +{
> +	unsigned char c;
> +	while (size) {
> +		c = (unsigned char)fgetc(stream);

Check for fgetc() returning EOF before converting to unsigned char.

> +/* load splited u-boot with PBI command 81xxxxxx. */

s/splited/split/

> +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);

Why do you need to tokenize if you're using getline()?

> +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, unsigned int len)
> +{
> +	unsigned int crc32_val = 0xffffffff;
> +	unsigned int 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;
> +}

Is this the standard CRC32 function (which we should be able to pull in
from elsewhere instead of reimplementing here) or is it something
different (which deserves a comment)?

> +static unsigned int reverse_byte(unsigned int val)
> +{
> +	unsigned int 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)
> +{
> +	unsigned int pbl_end_cmd[4] = {0x09138000, 0x00000000,
> +		0x091380c0, 0x00000000};

s/unsigned int/uint32_t/

> +	unsigned int 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]);
> +	}

Can you use htonl() or similar, to avoid the endian test?  Or have a
function to write out a 32-bit word by bytes, similar to what you
open-code in generate_pbl_cmd().


> +	for (i = 0; i < 16; i++) {
> +		*pmem_buf++ = *p++;
> +		mem_byte_cnt++;
> +	}

memcpy()?

> +	if (((mem_byte_cnt) % 16) != 0) {

Unnecessary parentheses.

> +		for (i = 0; i < 8; i++) {
> +			*pmem_buf++ = 0x0;
> +			mem_byte_cnt++;
> +		}
> +	}
> +	if ((mem_byte_cnt % 16 != 0)) {
> +		printf("Error: Bad size of image file\n");
> +		exit(EXIT_FAILURE);
> +	}
> +
> +}

No blank line at end of block.

> diff --git a/tools/pblimage.h b/tools/pblimage.h
> new file mode 100644
> index 0000000..887d4c9
> --- /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_

s/_PBLIMAGE_H_/PBLIMAGE_H/

Leading underscores are reserved to the C implementation when followed
by an uppercase letter or another underscore, or when in file scope.

I know most of the other tools/ headers do this, but it's wrong.

-Scott



More information about the U-Boot mailing list