mkimage: Add Kirkwood Boot Image support (kwbimage)

This patch adds support for "kwbimage" (Kirkwood Boot Image)
image types to the mkimage code.

For details refer to docs/README.kwbimage

This patch is tested with Sheevaplug board

Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
Acked-by: Ron Lee <ron@debian.org>

Signed-off-by: Prafulla Wadaskar <prafulla@marvell.com>
This commit is contained in:
Prafulla Wadaskar 2009-09-07 15:05:02 +05:30 committed by Wolfgang Denk
parent 7809fbb9aa
commit aa0c7a86cd
9 changed files with 619 additions and 0 deletions

View file

@ -324,6 +324,10 @@ $(obj)u-boot.img: $(obj)u-boot.bin
sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \
-d $< $@
$(obj)u-boot.kwb: $(obj)u-boot.bin
$(obj)tools/mkimage -n $(KWD_CONFIG) -T kwbimage \
-a $(TEXT_BASE) -e $(TEXT_BASE) -d $< $@
$(obj)u-boot.sha1: $(obj)u-boot.bin
$(obj)tools/ubsha1 $(obj)u-boot.bin
@ -3759,6 +3763,7 @@ clobber: clean
@rm -f $(OBJS) $(obj)*.bak $(obj)ctags $(obj)etags $(obj)TAGS \
$(obj)cscope.* $(obj)*.*~
@rm -f $(obj)u-boot $(obj)u-boot.map $(obj)u-boot.hex $(ALL)
@rm -f $(obj)u-boot.kwb
@rm -f $(obj)tools/{env/crc32.c,inca-swap-bytes}
@rm -f $(obj)cpu/mpc824x/bedbug_603e.c
@rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm

View file

@ -139,6 +139,7 @@ static table_entry_t uimage_type[] = {
{ IH_TYPE_SCRIPT, "script", "Script", },
{ IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
{ IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", },
{ IH_TYPE_KWBIMAGE, "kwbimage", "Kirkwood Boot Image",},
{ -1, "", "", },
};

93
doc/README.kwbimage Normal file
View file

@ -0,0 +1,93 @@
---------------------------------------------
Kirkwood Boot Image generation using mkimage
---------------------------------------------
This document describes the U-Boot feature as it
is implemented for the Kirkwood family of SoCs.
The Kirkwood SoC's can boot directly from NAND FLASH,
SPI FLASH, SATA etc. using its internal bootRom support.
for more details refer section 24.2 of Kirkwood functional specifications.
ref: www.marvell.com/products/embedded.../kirkwood/index.jsp
Command syntax:
--------------
./tools/mkimage -l <kwboot_file>
to list the kwb image file details
./tools/mkimage -n <board specific configuration file> \
-T kwbimage -a <start address> -e <execution address> \
-d <input_raw_binary> <output_kwboot_file>
for ex.
./tools/mkimage -n ./board/Marvell/openrd_base/kwbimage.cfg \
-T kwbimage -a 0x00600000 -e 0x00600000 \
-d u-boot.bin u-boot.kwb
kwimage support available with mkimage utility will generate kirkwood boot
image that can be flashed on the board NAND/SPI flash
Board specific configuration file specifications:
------------------------------------------------
1. This file must present in the $(BOARDDIR) and the name should be
kwbimage.cfg (since this is used in Makefile)
2. This file can have empty lines and lines starting with "#" as first
character to put comments
3. This file can have configuration command lines as mentioned below,
any other information in this file is treated as invalid.
Configuration command line syntax:
---------------------------------
1. Each command line is must have two strings, first one command or address
and second one data string
2. Following are the valid command strings and associated data strings:-
Command string data string
-------------- -----------
BOOT_FROM nand/spi/sata
NAND_ECC_MODE default/rs/hamming/disabled
NAND_PAGE_SIZE any uint16_t hex value
SATA_PIO_MODE any uint32_t hex value
DDR_INIT_DELAY any uint32_t hex value
DATA regaddr and regdara hex value
you can have maximum 55 such register programming commands
3. All commands are optional to program
Typical example of kwimage.cfg file:
-----------------------------------
# Boot Media configurations
BOOT_FROM nand
NAND_ECC_MODE default
NAND_PAGE_SIZE 0x0800
# Configure RGMII-0 interface pad voltage to 1.8V
DATA 0xFFD100e0 0x1b1b1b9b
# DRAM Configuration
DATA 0xFFD01400 0x43000c30
DATA 0xFFD01404 0x37543000
DATA 0xFFD01408 0x22125451
DATA 0xFFD0140C 0x00000a33
DATA 0xFFD01410 0x000000cc
DATA 0xFFD01414 0x00000000
DATA 0xFFD01418 0x00000000
DATA 0xFFD0141C 0x00000C52
DATA 0xFFD01420 0x00000040
DATA 0xFFD01424 0x0000F17F
DATA 0xFFD01428 0x00085520
DATA 0xFFD0147C 0x00008552
DATA 0xFFD01504 0x0FFFFFF1
DATA 0xFFD01508 0x10000000
DATA 0xFFD0150C 0x0FFFFFF5
DATA 0xFFD01514 0x00000000
DATA 0xFFD0151C 0x00000000
DATA 0xFFD01494 0x00030000
DATA 0xFFD01498 0x00000000
DATA 0xFFD0149C 0x0000E803
DATA 0xFFD01480 0x00000001
# End of Header extension
DATA 0x0 0x0
------------------------------------------------
Author: Prafulla Wadaskar <prafulla@marvell.com>

View file

@ -155,6 +155,7 @@
#define IH_TYPE_SCRIPT 6 /* Script file */
#define IH_TYPE_FILESYSTEM 7 /* Filesystem Image (any type) */
#define IH_TYPE_FLATDT 8 /* Binary Flat Device Tree Blob */
#define IH_TYPE_KWBIMAGE 9 /* Kirkwood Boot Image */
/*
* Compression Types

View file

@ -99,6 +99,7 @@ OBJ_FILES-y += fit_image.o
OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o
OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o
OBJ_FILES-$(CONFIG_INCA_IP) += inca-swap-bytes.o
OBJ_FILES-y += kwbimage.o
OBJ_FILES-y += mkimage.o
OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o
OBJ_FILES-y += os_support.o
@ -189,6 +190,7 @@ $(obj)mkimage$(SFX): $(obj)crc32.o \
$(obj)default_image.o \
$(obj)fit_image.o \
$(obj)image.o \
$(obj)kwbimage.o \
$(obj)md5.o \
$(obj)mkimage.o \
$(obj)os_support.o \
@ -218,6 +220,9 @@ $(obj)fit_image.o: $(SRCTREE)/tools/fit_image.c
$(obj)image.o: $(SRCTREE)/common/image.c
$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
$(obj)kwbimage.o: $(SRCTREE)/tools/kwbimage.c
$(CC) -g $(FIT_CFLAGS) -c -o $@ $<
$(obj)mkimage.o: $(SRCTREE)/tools/mkimage.c
$(CC) -g $(FIT_CFLAGS) -c -o $@ $<

405
tools/kwbimage.c Normal file
View file

@ -0,0 +1,405 @@
/*
* (C) Copyright 2008
* Marvell Semiconductor <www.marvell.com>
* Written-by: Prafulla Wadaskar <prafulla@marvell.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., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/* Required to obtain the getline prototype from stdio.h */
#define _GNU_SOURCE
#include "mkimage.h"
#include <image.h>
#include "kwbimage.h"
/*
* Supported commands for configuration file
*/
static table_entry_t kwbimage_cmds[] = {
{CMD_BOOT_FROM, "BOOT_FROM", "boot comand", },
{CMD_NAND_ECC_MODE, "NAND_ECC_MODE", "NAND mode", },
{CMD_NAND_PAGE_SIZE, "NAND_PAGE_SIZE", "NAND size", },
{CMD_SATA_PIO_MODE, "SATA_PIO_MODE", "SATA mode", },
{CMD_DDR_INIT_DELAY, "DDR_INIT_DELAY", "DDR init dly", },
{CMD_DATA, "DATA", "Reg Write Data", },
{CMD_INVALID, "", "", },
};
/*
* Supported Boot options for configuration file
*/
static table_entry_t kwbimage_bootops[] = {
{IBR_HDR_SPI_ID, "spi", "SPI Flash", },
{IBR_HDR_NAND_ID, "nand", "NAND Flash", },
{IBR_HDR_SATA_ID, "sata", "Sata port", },
{IBR_HDR_PEX_ID, "pex", "PCIe port", },
{IBR_HDR_UART_ID, "uart", "Serial port", },
{-1, "", "Invalid", },
};
/*
* Supported NAND ecc options configuration file
*/
static table_entry_t kwbimage_eccmodes[] = {
{IBR_HDR_ECC_DEFAULT, "default", "Default mode", },
{IBR_HDR_ECC_FORCED_HAMMING, "hamming", "Hamming mode", },
{IBR_HDR_ECC_FORCED_RS, "rs", "RS mode", },
{IBR_HDR_ECC_DISABLED, "disabled", "ECC Disabled", },
{-1, "", "", },
};
static struct kwb_header kwbimage_header;
static int datacmd_cnt = 0;
static char * fname = "Unknown";
static int lineno = -1;
/*
* Report Error if xflag is set in addition to default
*/
static int kwbimage_check_params (struct mkimage_params *params)
{
if (!strlen (params->imagename)) {
printf ("Error:%s - Configuration file not specified, "
"it is needed for kwbimage generation\n",
params->cmdname);
return CFG_INVALID;
}
return ((params->dflag && (params->fflag || params->lflag)) ||
(params->fflag && (params->dflag || params->lflag)) ||
(params->lflag && (params->dflag || params->fflag)) ||
(params->xflag) || !(strlen (params->imagename)));
}
static uint32_t check_get_hexval (char *token)
{
uint32_t hexval;
if (!sscanf (token, "%x", &hexval)) {
printf ("Error:%s[%d] - Invalid hex data(%s)\n", fname,
lineno, token);
exit (EXIT_FAILURE);
}
return hexval;
}
/*
* Generates 8 bit checksum
*/
static uint8_t kwbimage_checksum8 (void *start, uint32_t len, uint8_t csum)
{
register uint8_t sum = csum;
volatile uint8_t *p = (volatile uint8_t *)start;
/* check len and return zero checksum if invalid */
if (!len)
return 0;
do {
sum += *p;
p++;
} while (--len);
return (sum);
}
/*
* Generates 32 bit checksum
*/
static uint32_t kwbimage_checksum32 (uint32_t *start, uint32_t len, uint32_t csum)
{
register uint32_t sum = csum;
volatile uint32_t *p = start;
/* check len and return zero checksum if invalid */
if (!len)
return 0;
if (len % sizeof(uint32_t)) {
printf ("Error:%s[%d] - lenght is not in multiple of %d\n",
__FUNCTION__, len, sizeof(uint32_t));
return 0;
}
do {
sum += *p;
p++;
len -= sizeof(uint32_t);
} while (len > 0);
return (sum);
}
static void kwbimage_check_cfgdata (char *token, enum kwbimage_cmd cmdsw,
struct kwb_header *kwbhdr)
{
bhr_t *mhdr = &kwbhdr->kwb_hdr;
extbhr_t *exthdr = &kwbhdr->kwb_exthdr;
int i;
switch (cmdsw) {
case CMD_BOOT_FROM:
i = get_table_entry_id (kwbimage_bootops,
"Kwbimage boot option", token);
if (i < 0)
goto INVL_DATA;
mhdr->blockid = i;
printf ("Preparing kirkwood boot image to boot "
"from %s\n", token);
break;
case CMD_NAND_ECC_MODE:
i = get_table_entry_id (kwbimage_eccmodes,
"NAND ecc mode", token);
if (i < 0)
goto INVL_DATA;
mhdr->nandeccmode = i;
printf ("Nand ECC mode = %s\n", token);
break;
case CMD_NAND_PAGE_SIZE:
mhdr->nandpagesize =
(uint16_t) check_get_hexval (token);
printf ("Nand page size = 0x%x\n", mhdr->nandpagesize);
break;
case CMD_SATA_PIO_MODE:
mhdr->satapiomode =
(uint8_t) check_get_hexval (token);
printf ("Sata PIO mode = 0x%x\n",
mhdr->satapiomode);
break;
case CMD_DDR_INIT_DELAY:
mhdr->ddrinitdelay =
(uint16_t) check_get_hexval (token);
printf ("DDR init delay = %d msec\n", mhdr->ddrinitdelay);
break;
case CMD_DATA:
exthdr->rcfg[datacmd_cnt].raddr =
check_get_hexval (token);
break;
case CMD_INVALID:
goto INVL_DATA;
default:
goto INVL_DATA;
}
return;
INVL_DATA:
printf ("Error:%s[%d] - Invalid data\n", fname, lineno);
exit (EXIT_FAILURE);
}
/*
* this function sets the kwbimage header by-
* 1. Abstracting input command line arguments data
* 2. parses the kwbimage configuration file and update extebded header data
* 3. calculates header, extended header and image checksums
*/
static void kwdimage_set_ext_header (struct kwb_header *kwbhdr, char* name) {
bhr_t *mhdr = &kwbhdr->kwb_hdr;
extbhr_t *exthdr = &kwbhdr->kwb_exthdr;
FILE *fd = NULL;
int j;
char *line = NULL;
char * token, *saveptr1, *saveptr2;
size_t len = 0;
enum kwbimage_cmd cmd;
fname = name;
/* set dram register offset */
exthdr->dramregsoffs = (intptr_t)&exthdr->rcfg - (intptr_t)mhdr;
if ((fd = fopen (name, "r")) == 0) {
printf ("Error:%s - Can't open\n", fname);
exit (EXIT_FAILURE);
}
/* Simple kwimage.cfg file parser */
lineno=0;
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 (j = 0, cmd = CMD_INVALID, 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;
/* Process rest as valid config command line */
switch (j) {
case CFG_COMMAND:
cmd = get_table_entry_id (kwbimage_cmds,
"Kwbimage command", token);
if (cmd == CMD_INVALID)
goto INVL_CMD;
break;
case CFG_DATA0:
kwbimage_check_cfgdata (token, cmd, kwbhdr);
break;
case CFG_DATA1:
if (cmd != CMD_DATA)
goto INVL_CMD;
exthdr->rcfg[datacmd_cnt].rdata =
check_get_hexval (token);
if (datacmd_cnt > KWBIMAGE_MAX_CONFIG ) {
printf ("Error:%s[%d] - Found more "
"than max(%zd) allowed "
"data configurations\n",
fname, lineno,
KWBIMAGE_MAX_CONFIG);
exit (EXIT_FAILURE);
} else
datacmd_cnt++;
break;
default:
goto INVL_CMD;
}
j++;
}
}
if (line)
free (line);
fclose (fd);
return;
/*
* Invalid Command error reporring
*
* command CMD_DATA needs three strings on a line
* whereas other commands need only two.
*
* if more than two/three (as per command type) are observed,
* then error will be reported
*/
INVL_CMD:
printf ("Error:%s[%d] - Invalid command\n", fname, lineno);
exit (EXIT_FAILURE);
}
static void kwbimage_set_header (void *ptr, struct stat *sbuf, int ifd,
struct mkimage_params *params)
{
struct kwb_header *hdr = (struct kwb_header *)ptr;
bhr_t *mhdr = &hdr->kwb_hdr;
extbhr_t *exthdr = &hdr->kwb_exthdr;
uint32_t checksum;
int size;
/* Build and add image checksum header */
checksum = kwbimage_checksum32 ((uint32_t *)ptr, sbuf->st_size, 0);
size = write (ifd, &checksum, sizeof(uint32_t));
if (size != sizeof(uint32_t)) {
printf ("Error:%s - Checksum write %d bytes %s\n",
params->cmdname, size, params->imagefile);
exit (EXIT_FAILURE);
}
sbuf->st_size += sizeof(uint32_t);
mhdr->blocksize = sbuf->st_size - sizeof(struct kwb_header);
mhdr->srcaddr = sizeof(struct kwb_header);
mhdr->destaddr= params->addr;
mhdr->execaddr =params->ep;
mhdr->ext = 0x1; /* header extension appended */
kwdimage_set_ext_header (hdr, params->imagename);
/* calculate checksums */
mhdr->checkSum = kwbimage_checksum8 ((void *)mhdr, sizeof(bhr_t), 0);
exthdr->checkSum = kwbimage_checksum8 ((void *)exthdr,
sizeof(extbhr_t), 0);
}
static int kwbimage_verify_header (unsigned char *ptr, int image_size,
struct mkimage_params *params)
{
struct kwb_header *hdr = (struct kwb_header *)ptr;
bhr_t *mhdr = &hdr->kwb_hdr;
extbhr_t *exthdr = &hdr->kwb_exthdr;
uint8_t calc_hdrcsum;
uint8_t calc_exthdrcsum;
calc_hdrcsum = kwbimage_checksum8 ((void *)mhdr,
sizeof(bhr_t) - sizeof(uint8_t), 0);
if (calc_hdrcsum != mhdr->checkSum)
return -FDT_ERR_BADSTRUCTURE; /* mhdr csum not matched */
calc_exthdrcsum = kwbimage_checksum8 ((void *)exthdr,
sizeof(extbhr_t) - sizeof(uint8_t), 0);
if (calc_hdrcsum != mhdr->checkSum)
return -FDT_ERR_BADSTRUCTURE; /* exthdr csum not matched */
return 0;
}
static void kwbimage_print_header (const void *ptr)
{
struct kwb_header *hdr = (struct kwb_header *) ptr;
bhr_t *mhdr = &hdr->kwb_hdr;
char *name = get_table_entry_name (kwbimage_bootops,
"Kwbimage boot option",
(int) mhdr->blockid);
printf ("Image Type: Kirkwood Boot from %s Image\n", name);
printf ("Data Size: ");
genimg_print_size (mhdr->blocksize - sizeof(uint32_t));
printf ("Load Address: %08x\n", mhdr->destaddr);
printf ("Entry Point: %08x\n", mhdr->execaddr);
}
static int kwbimage_check_image_types (uint8_t type)
{
if (type == IH_TYPE_KWBIMAGE)
return EXIT_SUCCESS;
else
return EXIT_FAILURE;
}
/*
* kwbimage type parameters definition
*/
static struct image_type_params kwbimage_params = {
.name = "Kirkwood Boot Image support",
.header_size = sizeof(struct kwb_header),
.hdr = (void*)&kwbimage_header,
.check_image_type = kwbimage_check_image_types,
.verify_header = kwbimage_verify_header,
.print_header = kwbimage_print_header,
.set_header = kwbimage_set_header,
.check_params = kwbimage_check_params,
};
void init_kwb_image_type (void)
{
mkimage_register (&kwbimage_params);
}

106
tools/kwbimage.h Normal file
View file

@ -0,0 +1,106 @@
/*
* (C) Copyright 2008
* Marvell Semiconductor <www.marvell.com>
* Written-by: Prafulla Wadaskar <prafulla@marvell.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., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#ifndef _KWBIMAGE_H_
#define _KWBIMAGE_H_
#include <stdint.h>
#define KWBIMAGE_MAX_CONFIG ((0x1dc - 0x20)/sizeof(struct reg_config))
#define MAX_TEMPBUF_LEN 32
/* NAND ECC Mode */
#define IBR_HDR_ECC_DEFAULT 0x00
#define IBR_HDR_ECC_FORCED_HAMMING 0x01
#define IBR_HDR_ECC_FORCED_RS 0x02
#define IBR_HDR_ECC_DISABLED 0x03
/* Boot Type - block ID */
#define IBR_HDR_I2C_ID 0x4D
#define IBR_HDR_SPI_ID 0x5A
#define IBR_HDR_NAND_ID 0x8B
#define IBR_HDR_SATA_ID 0x78
#define IBR_HDR_PEX_ID 0x9C
#define IBR_HDR_UART_ID 0x69
#define IBR_DEF_ATTRIB 0x00
enum kwbimage_cmd {
CMD_INVALID,
CMD_BOOT_FROM,
CMD_NAND_ECC_MODE,
CMD_NAND_PAGE_SIZE,
CMD_SATA_PIO_MODE,
CMD_DDR_INIT_DELAY,
CMD_DATA
};
enum kwbimage_cmd_types {
CFG_INVALID = -1,
CFG_COMMAND,
CFG_DATA0,
CFG_DATA1
};
/* typedefs */
typedef struct bhr_t {
uint8_t blockid; /*0 */
uint8_t nandeccmode; /*1 */
uint16_t nandpagesize; /*2-3 */
uint32_t blocksize; /*4-7 */
uint32_t rsvd1; /*8-11 */
uint32_t srcaddr; /*12-15 */
uint32_t destaddr; /*16-19 */
uint32_t execaddr; /*20-23 */
uint8_t satapiomode; /*24 */
uint8_t rsvd3; /*25 */
uint16_t ddrinitdelay; /*26-27 */
uint16_t rsvd2; /*28-29 */
uint8_t ext; /*30 */
uint8_t checkSum; /*31 */
} bhr_t, *pbhr_t;
struct reg_config {
uint32_t raddr;
uint32_t rdata;
};
typedef struct extbhr_t {
uint32_t dramregsoffs;
uint8_t rsrvd1[0x20 - sizeof(uint32_t)];
struct reg_config rcfg[KWBIMAGE_MAX_CONFIG];
uint8_t rsrvd2[7];
uint8_t checkSum;
} extbhr_t, *pextbhr_t;
struct kwb_header {
bhr_t kwb_hdr;
extbhr_t kwb_exthdr;
};
/*
* functions
*/
void init_kwb_image_type (void);
#endif /* _KWBIMAGE_H_ */

View file

@ -148,6 +148,8 @@ main (int argc, char **argv)
int retval = 0;
struct image_type_params *tparams = NULL;
/* Init Kirkwood Boot image generation/list support */
init_kwb_image_type ();
/* Init FIT image generation/list support */
init_fit_image_type ();
/* Init Default image generation/list support */

View file

@ -139,6 +139,7 @@ void mkimage_register (struct image_type_params *tparams);
*
* Supported image types init functions
*/
void init_kwb_image_type (void);
void init_default_image_type (void);
void init_fit_image_type (void);