diff -bwpurN zelk-0.9.0/u-boot/common/cmd_bin.c u-boot/common/cmd_bin.c --- zelk-0.9.0/u-boot/common/cmd_bin.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot/common/cmd_bin.c 2005-04-01 17:24:06.000000000 +0200 @@ -0,0 +1,286 @@ +/* + * (C) Copyright 2004 + * Andrea Scian, Dave Srl, andrea.scian@dave-tech.it + * + * 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 + * + */ + + +#include +#include +#include +#include +#include + + +#if (CONFIG_COMMANDS & CFG_CMD_BIN) + +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +#undef CMD_BIN_DEBUG + + +#ifdef CMD_BIN_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#endif + +/* ====================================================================== + * BIN file type definition + * ====================================================================== */ + +#define NUM_SYNCBYTES 7 + +#define SYNC_MAGIC "B000FF\n" + +struct bin_sync { + unsigned char syncbytes[NUM_SYNCBYTES]; +}; + +struct bin_header { + unsigned int img_start; + unsigned int img_length; +}; + +#define BASE_BIN_RECORD_SIZE 12 + +struct bin_record { + unsigned int address; + unsigned int length; + unsigned int checksum; + /* + ** unsigned char data[length]; + */ +}; + +extern int build_bin_image_parameters(char* cmdline); + +int valid_bin_image (unsigned long addr); +unsigned long load_bin_image (unsigned long addr); + + +/* ====================================================================== + * Interpreter command to boot WindowsCE from a memory image. The image can + * be either a .bin image or a raw binary (nb0). Will attempt to setup the + * bootline and other parameters correctly. + * ====================================================================== */ +int do_bootwince ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +#if defined(CONFIG_WALNUT405) || \ + defined(CONFIG_CPCI405) || \ + defined(CONFIG_OCRTC) || \ + defined(CONFIG_ORSG) + DECLARE_GLOBAL_DATA_PTR; +#endif + + unsigned long addr; /* Address of image */ + unsigned long bootaddr; /* Address to put the bootline */ + char *bootline; /* Text of the bootline */ + char *tmp; /* Temporary char pointer */ + + char build_buf[80]; /* Buffer for building the bootline */ + + volatile unsigned int value; + + /* + * Check the loadaddr variable. + * If we don't know where the image is then we're done. + */ + + if (argc>1) { + addr = simple_strtoul (argv[1], NULL, 16); + } else if ((tmp = getenv ("loadaddr")) != NULL) { + addr = simple_strtoul (tmp, NULL, 16); + } else { + puts ("No load address provided!\n"); + return 1; + } + +#if (CONFIG_COMMANDS & CFG_CMD_NET) + /* Check to see if we need to tftp the image ourselves before starting */ + + if ((argc == 2) && (strcmp (argv[1], "tftp") == 0)) { + if (NetLoop (TFTP) <= 0) + return 1; + printf ("Automatic boot of WindowsCE image at address 0x%04x ... \n", addr); + } +#endif + + /* + * Use bootaddr to find the location in memory that WindowsCE + * will look for the bootline string. The default value for + * PowerPC is LOCAL_MEM_LOCAL_ADRS + BOOT_LINE_OFFSET which + * defaults to 0x4200 + */ + if ((tmp = getenv ("bootaddr")) == NULL) + bootaddr = PHYS_SDRAM_1 | 0x4200; + else + bootaddr = simple_strtoul (tmp, NULL, 16); + + /* + * Check to see if the bootline is defined in the 'bootargs' + * parameter. If it is not defined, we may be able to + * construct the info + */ + + if ((bootline = getenv ("bootargs")) != NULL) { + memcpy ((void *) bootaddr, bootline, MAX(strlen(bootline), 512)); + flush_cache (bootaddr, MAX(strlen(bootline), 512)); + } else { + /* there is no command line! */ + memset ((void *) bootaddr, 0, 512); + } + +#ifdef CONFIG_BUILD_BIN_PARAM + build_bin_image_parameters(bootaddr); +#endif + + /* + * If the data at the load address is an elf image, then + * treat it like an elf image. Otherwise, assume that it is a + * binary image + */ + + printf ("## Loading WindowsCE binary image from 0x%04x, please wait...\n", addr); + + if (valid_bin_image (addr)) { + addr = load_bin_image (addr+NUM_SYNCBYTES); + } else { + puts ("## Not an WinCE BIN image, assuming absolute binary image (.nb0)\n"); + /* leave addr as load_addr */ + } + + if (addr==(unsigned long)0xFFFFFFFF) { + printf ("## ABORTING: wrong CRC\n"); + return 1; + } + + PRINTF ("## Using bootline (@ 0x%lx): %s\n", bootaddr, + (char *) bootaddr); + printf ("## Starting WindowsCE at 0x%04x ...\n", addr); + + ((void (*)(void)) addr) (); + + /* we should NEVER get here! */ + + puts ("## WindowsCE terminated\n"); + return 1; +} + +/* ====================================================================== + * Determine if a valid BIN image exists at the given memory location. + * Looks at the BIN header magic field. + * ====================================================================== */ +int valid_bin_image (unsigned long addr) +{ + struct bin_sync* sync; + + sync = (struct bin_sync*) addr; + + if (strncmp(sync->syncbytes, SYNC_MAGIC, NUM_SYNCBYTES) == 0) + return 1; + else return 0; +} + + +/* ====================================================================== + * A simple WinCE BIN loader, assumes the image is valid, returns the + * entry point address. + * ====================================================================== */ +unsigned long load_bin_image (unsigned long addr) +{ + int i; + unsigned long current_addr; + unsigned long dest_addr; + unsigned long current_dest_addr; + struct bin_header header; + struct bin_record record; + int record_num; + long int record_checksum; + + /* read bin header */ + + memcpy((char*)&header, (char*)addr, sizeof(header)); + + PRINTF("#### .bin image header data:\n"); + PRINTF("#### start 0x%04x, size 0x%04x\n", header.img_start, + header.img_length); + + current_addr = addr + sizeof(struct bin_header); + current_dest_addr = header.img_start; + + record_num = 0; + while (1) { + /* read record */ + memcpy((char*)&record, (char*)current_addr, sizeof(record)); + + PRINTF("#### .bin record #%d:\n", record_num); + PRINTF("#### start 0x%04x, size 0x%04x, chksum 0x%04x\n", + record.address, record.length, record.checksum); + + if (record.address==0) { + PRINTF("#### address==0->quitting!\n"); + break; + } + + current_addr += BASE_BIN_RECORD_SIZE; + + /* checksum verification */ + record_checksum = 0; + for (i=0; i