Beispiel #1
0
/*
************************************************************************************************************
*
*                                             function
*
*    name          :
*
*    parmeters     :
*
*    return        :
*
*    note          :
*
*
************************************************************************************************************
*/
static void __continue(void)
{
	char response[32];

	memset(response, 0, 32);
	strcpy(response,"OKAY");

	__sunxi_fastboot_send_status(response, strlen(response));

	sunxi_usb_exit();

	if(uboot_spare_head.boot_data.storage_type)
	{
		setenv("bootcmd", "run setargs_mmc boot_normal");
	}
	else
	{
		setenv("bootcmd", "run setargs_nand boot_normal");
	}
	do_bootd(NULL, 0, 1, NULL);

	return;
}
static int rx_handler (const unsigned char *buffer, unsigned int buffer_size)
{
	int ret = 1;

	/* Use 65 instead of 64
	   null gets dropped  
	   strcpy's need the extra byte */
	char response[65];

	if (download_size) 
	{
		/* Something to download */

		if (buffer_size)
		{
			/* Handle possible overflow */
			unsigned int transfer_size = 
				download_size - download_bytes;

			if (buffer_size < transfer_size)
				transfer_size = buffer_size;
			
			/* Save the data to the transfer buffer */
			memcpy (interface.transfer_buffer + download_bytes, 
				buffer, transfer_size);

			download_bytes += transfer_size;
			
			/* Check if transfer is done */
			if (download_bytes >= download_size) {
				/* Reset global transfer variable,
				   Keep download_bytes because it will be
				   used in the next possible flashing command */
				download_size = 0;

				if (download_error) {
					/* There was an earlier error */
					sprintf(response, "ERROR");
				} else {
					/* Everything has transferred,
					   send the OK response */
					sprintf(response, "OKAY");
				}
				fastboot_tx_status(response, strlen(response));

				printf ("\ndownloading of %d bytes finished\n",
					download_bytes);

				/* Padding is required only if storage medium is NAND */
				if (interface.storage_medium == NAND) {
					/* Pad to block length
					   In most cases, padding the download to be
					   block aligned is correct. The exception is
					   when the following flash writes to the oob
					   area.  This happens when the image is a
					   YAFFS image.  Since we do not know what
					   the download is until it is flashed,
					   go ahead and pad it, but save the true
					   size in case if should have
					   been unpadded */
					download_bytes_unpadded = download_bytes;
					if (interface.nand_block_size)
					{
						if (download_bytes %
						    interface.nand_block_size)
						{
							unsigned int pad = interface.nand_block_size - (download_bytes % interface.nand_block_size);
							unsigned int i;

							for (i = 0; i < pad; i++)
							{
								if (download_bytes >= interface.transfer_buffer_size)
									break;

								interface.transfer_buffer[download_bytes] = 0;
								download_bytes++;
							}
						}
					}
				}
			}

			/* Provide some feedback */
			if (download_bytes &&
			    0 == (download_bytes %
				  (16 * interface.nand_block_size)))
			{
				/* Some feeback that the
				   download is happening */
				if (download_error)
					printf("X");
				else
					printf(".");
				if (0 == (download_bytes %
					  (80 * 16 *
					   interface.nand_block_size)))
					printf("\n");
				
			}
		}
		else
		{
			/* Ignore empty buffers */
			printf ("Warning empty download buffer\n");
			printf ("Ignoring\n");
		}
		ret = 0;
	}
	else
	{
		/* A command */
#if defined(CONFIG_MACH_BOWSER_SUBTYPE_TATE)
        fastboot_confirmed=1;
#endif
		/* Cast to make compiler happy with string functions */
		const char *cmdbuf = (char *) buffer;

		/* Generic failed response */
		sprintf(response, "FAIL");


		/* continue
		   Continue booting as normal (if possible) */
		if(memcmp(cmdbuf, "continue", 8) == 0) {
			sprintf(response, "OKAY");
			fastboot_tx_status(response, strlen(response));

			printf ("Booting kernel..\n");

			do_bootd(NULL, 0, 0, NULL);

			sprintf(response, "FAIL: invalid boot image");
			ret = 0;
		}

		/* reboot 
		   Reboot the board. */
		if(memcmp(cmdbuf, "reboot-bootloader", 17) == 0)
		{
			sprintf(response,"OKAY");
			fastboot_tx_status(response, strlen(response));

			/* Clear all reset reasons */
			__raw_writel(0xfff, PRM_RSTST);

			strcpy(PUBLIC_SAR_RAM_1_FREE, "bootloader");

			/* now warm reset the silicon */
			__raw_writel(PRM_RSTCTRL_RESET_WARM_BIT,
					PRM_RSTCTRL);
			return 0;
		}

		if(memcmp(cmdbuf, "reboot", 6) == 0) 
		{
			sprintf(response,"OKAY");
			fastboot_tx_status(response, strlen(response));

			strcpy(PUBLIC_SAR_RAM_1_FREE, "");

			do_reset (NULL, 0, 0, NULL);
			
			/* This code is unreachable,
			   leave it to make the compiler happy */
			return 0;
		}
		
		/* getvar
		   Get common fastboot variables
		   Board has a chance to handle other variables */
		if(memcmp(cmdbuf, "getvar:", 7) == 0) 
		{
			int get_var_length = strlen("getvar:");

			strcpy(response,"OKAY");

			if(!strcmp(cmdbuf + get_var_length, "version")) {
				strcpy(response + 4, FASTBOOT_VERSION);

			} else if(!strcmp(cmdbuf + get_var_length, "product")) {
				if (interface.product_name)
					strcpy(response + 4, interface.product_name);

			} else if(!strcmp(cmdbuf + get_var_length, "serialno")) {
				if (interface.serial_no)
					strcpy(response + 4, interface.serial_no);

			} else if(!strcmp(cmdbuf + get_var_length, "downloadsize")) {
				if (interface.transfer_buffer_size)
					sprintf(response + 4, "%08x", interface.transfer_buffer_size);
			} else if(!strcmp(cmdbuf + get_var_length, "max-download-size")) {
				if (interface.transfer_buffer_size) 
					sprintf(response + 4, "%lu", interface.transfer_buffer_size);
			} else if(!strcmp(cmdbuf + get_var_length, "cpurev")) {
				if (interface.proc_rev)
					strcpy(response + 4, interface.proc_rev);
			} else if(!strcmp(cmdbuf + get_var_length, "secure")) {
				if (interface.proc_type)
					strcpy(response + 4, interface.proc_type);
			} else {
				fastboot_getvar(cmdbuf + 7, response + 4);
			}
			ret = 0;

		}

		/* %fastboot oem <cmd> */
		if (memcmp(cmdbuf, "oem ", 4) == 0) {

			ret = 0;
			cmdbuf += 4;

			if (memcmp(cmdbuf, "shutdown", 8) == 0) {
				sprintf(response, "SHUTDOWN");
				fastboot_tx_status(response, strlen(response));
				do_powerdown ();
			}

#if defined(CONFIG_MACH_BOWSER_SUBTYPE_TATE)
	        if (memcmp(cmdbuf, "idme ", 5) == 0) {
			ret = fastboot_idme(cmdbuf + 5);
		if (ret) {
				strcpy(response,"FAIL");
			} else {
				strcpy(response,"OKAY");
			}
			ret = 0;
			goto done;
		}
#endif

			/* fastboot oem format */
			if(memcmp(cmdbuf, "format", 6) == 0){
				ret = fastboot_oem(cmdbuf);
				if (ret < 0) {
					strcpy(response,"FAIL");
				} else {
					strcpy(response,"OKAY");
				}
				goto done;
			}

			/* fastboot oem recovery */
			if(memcmp(cmdbuf, "recovery", 8) == 0){
				sprintf(response,"OKAY");
				fastboot_tx_status(response, strlen(response));

				/* Clear all reset reasons */
				__raw_writel(0xfff, PRM_RSTST);
				strcpy(PUBLIC_SAR_RAM_1_FREE, "recovery");
				/* now warm reset the silicon */
				__raw_writel(PRM_RSTCTRL_RESET_WARM_BIT,
					PRM_RSTCTRL);
				/* Never returns */
				while(1);
			}

			/* fastboot oem unlock */
			if(memcmp(cmdbuf, "unlock", 6) == 0){
				sprintf(response,"FAIL");
				printf("\nfastboot: oem unlock "\
						"not implemented yet!!\n");
				goto done;
			}

			/* fastboot oem [xxx] */
			printf("\nfastboot: do not understand oem %s\n", cmdbuf);
			strcpy(response,"FAIL");
			goto done;
		} /* end: %fastboot oem <cmd> */

		/* erase
		   Erase a register flash partition
		   Board has to set up flash partitions */

		if(memcmp(cmdbuf, "erase:", 6) == 0){

			if (interface.storage_medium == NAND) {
				/* storage medium is NAND */

				struct fastboot_ptentry *ptn;

				ptn = fastboot_flash_find_ptn(cmdbuf + 6);
				if (ptn == 0)
				{
					sprintf(response, "FAILpartition does not exist");
				}
				else
				{
					char start[32], length[32];
					int status = 0, repeat, repeat_max;

					printf("erasing '%s'\n", ptn->name);

					char *lock[5]   = { "nand", "lock",   NULL, NULL, NULL, };
					char *unlock[5] = { "nand", "unlock", NULL, NULL, NULL,	};
					char *erase[5]  = { "nand", "erase",  NULL, NULL, NULL, };

					lock[2] = unlock[2] = erase[2] = start;
					lock[3] = unlock[3] = erase[3] = length;

					repeat_max = 1;
					if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK)
						repeat_max = ptn->flags & FASTBOOT_PTENTRY_FLAGS_REPEAT_MASK;

					sprintf (length, "0x%x", ptn->length);
					for (repeat = 0; repeat < repeat_max; repeat++)
					{
						sprintf (start, "0x%x", ptn->start + (repeat * ptn->length));
#if 0
						do_nand (NULL, 0, 4, unlock);
						status = do_nand (NULL, 0, 4, erase);
						do_nand (NULL, 0, 4, lock);
#endif

						if (status)
							break;
					}

					if (status)
					{
						sprintf(response, "FAILfailed to erase partition");
					}
					else
					{
						printf("partition '%s' erased\n", ptn->name);
						sprintf(response, "OKAY");
					}
				}
			} else if (interface.storage_medium == EMMC) {
				/* storage medium is EMMC */

				struct fastboot_ptentry *ptn;

				/* Save the MMC controller number */
#if  defined(CONFIG_4430PANDA)
				/* panda board does not have eMMC on mmc1 */
				mmc_controller_no = 0;
#else
				/* blaze has emmc on mmc1 */
				mmc_controller_no = 1;
#endif

				/* Find the partition and erase it */
				ptn = fastboot_flash_find_ptn(cmdbuf + 6);

				if (ptn == 0) {
					sprintf(response,
					"FAIL: partition doesn't exist");
				} else {
					/* Call MMC erase function here */
					char start[32], length[32];
					char slot_no[32];

					char *erase[5]  = { "mmc", NULL, "erase",
							NULL, NULL, };
					char *mmc_init[2] = {"mmcinit", NULL,};

					mmc_init[1] = slot_no;
					erase[1] = slot_no;
					erase[3] = start;
					erase[4] = length;

					sprintf(slot_no, "%d", mmc_controller_no);
					sprintf(length, "0x%x", ptn->length);
					sprintf(start, "0x%x", ptn->start);

					printf("Initializing '%s'\n", ptn->name);
					if (do_mmc(NULL, 0, 2, mmc_init))
						sprintf(response, "FAIL: Init of MMC card");
					else
						sprintf(response, "OKAY");


					printf("Erasing '%s'\n", ptn->name);
					if (do_mmc(NULL, 0, 5, erase)) {
						printf("Erasing '%s' FAILED!\n", ptn->name);
						sprintf(response, "FAIL: Erase partition");
					} else {
						printf("Erasing '%s' DONE!\n", ptn->name);
						sprintf(response, "OKAY");
					}
				}
			}

			ret = 0;
		}


		/* EMMC Erase
		   Erase a register flash partition on MMC
		   Board has to set up flash partitions */
		if (memcmp(cmdbuf, "mmcerase:", 9) == 0) {
			struct fastboot_ptentry *ptn;

			/* Save the MMC controller number */
			mmc_controller_no = simple_strtoul(cmdbuf + 9,
								NULL, 10);
			/* Find the partition and erase it */
			ptn = fastboot_flash_find_ptn(cmdbuf + 11);

			if (ptn == 0) {
				sprintf(response,
					"FAIL: partition doesn't exist");
			} else {
				/* Call MMC erase function here */
				/* This is not complete */
				char start[32], length[32];
				char slot_no[32];

				char *erase[5]  = { "mmc", NULL, "erase",
								NULL, NULL, };
				char *mmc_init[2] = {"mmcinit", NULL,};

				mmc_init[1] = slot_no;
				erase[1] = slot_no;
				erase[3] = start;
				erase[4] = length;

				sprintf(slot_no, "%d", mmc_controller_no);
				sprintf(length, "0x%x", ptn->length);
				sprintf(start, "0x%x", ptn->start);

				printf("Initializing '%s'\n", ptn->name);
				if (do_mmc(NULL, 0, 2, mmc_init)) {
					sprintf(response, "FAIL: Init of MMC card");
				} else {
					sprintf(response, "OKAY");
				}

				printf("Erasing '%s'\n", ptn->name);
				if (do_mmc(NULL, 0, 5, erase)) {
					sprintf(response, "FAIL: Erase partition");
				} else {
					sprintf(response, "OKAY");
				}
			}
		}

		/* download
		   download something .. 
		   What happens to it depends on the next command after data */
		if(memcmp(cmdbuf, "download:", 9) == 0) {

			/* save the size */
			download_size = simple_strtoul(cmdbuf + 9, NULL, 16);
			/* Reset the bytes count, now it is safe */
			download_bytes = 0;
			/* Reset error */
			download_error = 0;

			printf("Starting download of %d bytes\n",
							download_size);

			if (0 == download_size)
			{
				/* bad user input */
				sprintf(response, "FAILdata invalid size");
			} else if (download_size >
						interface.transfer_buffer_size)
			{
				/* set download_size to 0
				 * because this is an error */
				download_size = 0;
				sprintf(response, "FAILdata too large");
			}
			else
			{
				/* The default case, the transfer fits
				   completely in the interface buffer */
				sprintf(response, "DATA%08x", download_size);
			}
			ret = 0;
		}

		/* boot
		   boot what was downloaded
		   **
		   ** +-----------------+
		   ** | boot header     | 1 page
		   ** +-----------------+
		   ** | kernel          | n pages
		   ** +-----------------+
		   ** | ramdisk         | m pages
		   ** +-----------------+
		   ** | second stage    | o pages
		   ** +-----------------+
		   **
		   Pagesize has default value of
		   CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE
		*/

		if(memcmp(cmdbuf, "boot", 4) == 0) {

			if ((download_bytes) &&
			    (CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE < download_bytes))
			{
				char start[32];
				char *booti_args[4] = { "booti", NULL, "boot", NULL };

				/* Skip the mkbootimage header */
				//boot_img_hdr *hdr =
				//	(boot_img_hdr *)
				//	&interface.transfer_buffer[CFG_FASTBOOT_MKBOOTIMAGE_PAGE_SIZE];

				booti_args[1] = start;
				sprintf (start, "0x%x", interface.transfer_buffer);

				/* Execution should jump to kernel so send the response
				   now and wait a bit.  */
				sprintf(response, "OKAY");
				fastboot_tx_status(response, strlen(response));

				printf ("Booting kernel..\n");

				/* For Future use
				 *	if (strlen ((char *) &fb_hdr->cmdline[0]))
				 *		set_env ("bootargs", (char *) &fb_hdr->cmdline[0]);
				 */
				/* boot the boot.img */
				do_booti (NULL, 0, 3, booti_args);
			}
			sprintf(response, "FAILinvalid boot image");
			ret = 0;
		}

		/* mmcwrite
		   write what was downloaded on MMC*/
				/* Write to MMC whatever was downloaded */
		if (memcmp(cmdbuf, "mmcwrite:", 9) == 0) {

			if (download_bytes) {

				struct fastboot_ptentry *ptn;

				/* Save the MMC controller number */
				mmc_controller_no = simple_strtoul(cmdbuf + 9, NULL, 10);

				/* Next is the partition name */
				ptn = fastboot_flash_find_ptn(cmdbuf + 11);

				if (ptn == 0) {
					sprintf(response, "FAILpartition does not exist");
				} else {
					write_to_ptn_emmc(ptn, 0, response);
				}

			} else {
				sprintf(response, "FAILno image downloaded");
			}
		}


		/* flash
		   Flash what was downloaded */

		if(memcmp(cmdbuf, "flash:", 6) == 0) {

			if (interface.storage_medium == NAND) {
				/* storage medium is NAND */

				if (download_bytes)
				{
					struct fastboot_ptentry *ptn;

					ptn = fastboot_flash_find_ptn(cmdbuf + 6);
					if (ptn == 0) {
						sprintf(response, "FAILpartition does not exist");
					} else if ((download_bytes > ptn->length) &&
						   !(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV)) {
						sprintf(response, "FAILimage too large for partition");
						/* TODO : Improve check for yaffs write */
					} else {
						/* Check if this is not really a flash write
						   but rather a saveenv */
						if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) {
							/* Since the response can only be 64 bytes,
							   there is no point in having a large error message. */
							char err_string[32];
							if (saveenv_to_ptn(ptn, &err_string[0])) {
								printf("savenv '%s' failed : %s\n", ptn->name, err_string);
								sprintf(response, "FAIL%s", err_string);
							} else {
								printf("partition '%s' saveenv-ed\n", ptn->name);
								sprintf(response, "OKAY");
							}
						} else {
							/* Normal case */
							if (write_to_ptn(ptn)) {
								printf("flashing '%s' failed\n", ptn->name);
								sprintf(response, "FAILfailed to flash partition");
							} else {
								printf("partition '%s' flashed\n", ptn->name);
								sprintf(response, "OKAY");
							}
						}
					}
				}
				else
				{
					sprintf(response, "FAILno image downloaded");
				}
			} else if (interface.storage_medium == EMMC) {
				/* storage medium is EMMC */

				if (download_bytes) {

					struct fastboot_ptentry *ptn;
					char *argv[2] = {NULL, "-f"};

					/* Next is the partition name */
					ptn = fastboot_flash_find_ptn(cmdbuf + 6);

					if (ptn == 0) {
						printf("Partition:'%s' does not exist\n", ptn->name);
						sprintf(response, "FAILpartition does not exist");
					} else if ((download_bytes > ptn->length) &&
						!(ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV)) {
						printf("Image too large for the partition\n");
						sprintf(response, "FAILimage too large for partition");
						} else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) {
						/* Check if this is not really a flash write,
						 * but instead a saveenv
						 */
						unsigned int i = 0;
						/* Env file is expected with a NULL delimeter between
						 * env variables So replace New line Feeds (0x0a) with
						 * NULL (0x00)
						 */
						for (i = 0; i < download_bytes; i++) {
							if (interface.transfer_buffer[i] == 0x0a)
								interface.transfer_buffer[i] = 0x00;
						}
						memset(env_ptr->data, 0, ENV_SIZE);
						memcpy(env_ptr->data, interface.transfer_buffer, download_bytes);
						do_saveenv(NULL, 0, 2, argv);
						printf("saveenv to '%s' DONE!\n", ptn->name);
						sprintf(response, "OKAY");
					} else {
						write_to_ptn_emmc(ptn, 0, response);
					} /* Normal Case */

				} else {
					sprintf(response, "FAILno image downloaded");
				}
			} /* EMMC */

			ret = 0;
		} /* fastboot flash ... */

	/* multi-flash support */

		if(memcmp(cmdbuf, "multiflash:", 11) == 0) {

			if (interface.storage_medium == NAND) {
				sprintf(response, "FAILmultiflash is not supported for NAND");
			} else if (interface.storage_medium == EMMC) {
				/* storage medium is EMMC */

				if (download_bytes) {

					struct fastboot_ptentry *ptn;
					/* Next is the partition name */
					ptn = fastboot_flash_find_ptn(cmdbuf + 13);

					if(ptn != multiflash_ptn) {
						// If we start flashing a new partitionn reset
						// multi flash statics
						multiflash_ptn    = ptn;
						multiflash_offset = 0;
					}

					if (ptn == 0) {
						printf("Partition:'%s' does not exist\n", ptn->name);
						sprintf(response, "FAILpartition does not exist");
					} else if (ptn->flags & FASTBOOT_PTENTRY_FLAGS_WRITE_ENV) {
						printf("Multiflash canno be used with partition :'%s'\n",
						       ptn->name);
						sprintf(response, "FAILpartition not supported with multiflash");
                                        } else if((download_bytes+multiflash_offset) > ptn->length) {
						printf("Image too large for the partition\n");
						sprintf(response, "FAILimage too large for partition");
					} else {
						printf("\nflash image chunk: offset=@0x%08X size=0x%04X\n",
						       multiflash_offset, download_bytes);

						if(!write_to_ptn_emmc(ptn, multiflash_offset, response)) {
							if(memcmp(cmdbuf + 11, "1", 1) == 0) {
								// it was the last chunk
								multiflash_offset = 0;
								multiflash_ptn    = NULL;
							} else {
								multiflash_offset += download_bytes;
							}
						}
					} /* Normal Case */

				} else {
					sprintf(response, "FAILno image downloaded");
				}
			} /* EMMC */

			ret = 0;
		} /* fastboot multiflash ... */


done:
		fastboot_tx_status(response, strlen(response));

	} /* End of command */
	
	return ret;
}
Beispiel #3
0
//extern int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
void recoveryHandle(void)
{
	char cmd[256];
	char img[10];
	char * argv[3];
	char *env;
	MV_32 imagAddr, imagSize = 0, netflag = 1;
	char ip[16]= {"dhcp"};
	char* usbload[5];
	unsigned int netwait = 3000;
	int upgrade = -1;
	
	/* get the loadaddr env var */
	if (!getenv("loadaddr")) {
		printf("Missing loadaddr environment variable assuming default (%s)!\n", RCVR_LOAD_ADDR);
		setenv("loadaddr",RCVR_LOAD_ADDR);
		saveenv();
	}

#ifdef CONFIG_USB_STORAGE
	/* First try to perform recovery from USB DOK*/
	/* try to recognize storage devices immediately */
	if (usb_init() >= 0)
	{
		if (usb_stor_scan(1) >= 0)
		{
			netflag = 0;
			usbload[0] = "usbload";
			usbload[1] = "usb";
			usbload[2] = "0:1";
			usbload[3] = getenv("loadaddr");
			usbload[4] = "/multiware.img";

			printf("Trying to load image from USB flash drive using FAT FS\n");
			if (do_fat_fsload(0, 0, 5, usbload) == 1)
			{
				printf("Trying to load image from USB flash drive using ext2 FS partition 0\n");
				usbload[2] = "0:0";
				if(do_ext2load(0, 0, 5, usbload) == 1)
				{
					printf("Trying to load image from USB flash drive using ext2 FS partition 1\n");
					usbload[2] = "0:1";
					if(do_ext2load(0, 0, 5, usbload) == 1)
					{
						printf("Couldn't load recovery image from USB flash drive, Trying network interface\n");
						netflag = 1;
					}
					else
					{
						env = getenv("filesize");
						usbload[3] = getenv("loadaddr");
						imagSize = simple_strtoul(env, NULL, 16); /* get the filesize env var */
			
						/* Trying to check if we forced to upgrade by placing upgrade.me */
						usbload[4] = "/upgrade.me";
						usbload[3] = "0x000000000";
						env=getenv("loadaddr");
						imagAddr=simple_strtoul(env, NULL, 16);
						sprintf(usbload[3], "0x%x", imagAddr + imagSize + 1);
						printf("dummyaddr:%s\n", usbload[3]);
						upgrade=do_ext2load(0, 0, 5, usbload);
					}
				}
				else
				{
					env = getenv("filesize");
					imagSize = simple_strtoul(env, NULL, 16); /* get the filesize env var */

					/* Trying to check if we forced to upgrade by placing upgrade.me */
					usbload[4] = "/upgrade.me";
					usbload[3] = "0x000000000";
					env=getenv("loadaddr");
					imagAddr=simple_strtoul(env, NULL, 16);
					sprintf(usbload[3], "0x%x", imagAddr + imagSize + 1);
					printf("dummyaddr:%s\n", usbload[3]);
					upgrade=do_ext2load(0, 0, 5, usbload);
				}
			}
			else
			{
				env = getenv("filesize");
				imagSize = simple_strtoul(env, NULL, 16); /* get the filesize env var */

				/* Trying to check if we forced to upgrade by placing upgrade.me */
				usbload[4] = "/upgrade.me";
				usbload[3] = "0x000000000";
				env=getenv("loadaddr");
				imagAddr=simple_strtoul(env, NULL, 16);
				sprintf(usbload[3], "0x%x", imagAddr + imagSize + 1);
				printf("dummyaddr:%s\n", usbload[3]);
				upgrade=do_fat_fsload(0, 0, 5, usbload);
			}

			// Decide on upgrade/init mode
			if (upgrade == 0)
				sprintf(ip, "usb_upgrade");
			else
				sprintf(ip, "usb");
			printf("USB mode:%s\n", ip);
		}
	}
#endif

	if(netflag == 1)
	{
		/* if recovery ip set same as our ip then skip dhcp */
		while ( strcmp(getenv("rcvrip"), getenv("ipaddr")) && (netwait > 0) )
		{
			/* Perform the DHCP */
			printf("Aquiring an IP address using DHCP after delay...\n");
			mvOsDelay(netwait);
			netwait-=1000;

			if (NetLoop(DHCP) != -1)
			{
				/* We'vev got DHCP progressing with recovery */
				printf("DHCP should be ready for Recovery.\n");
				break;
			}
		}

		/* No DHCP after timeout or forced */
		if ( !strcmp(getenv("rcvrip"), getenv("ipaddr")) || (netwait <= 0) )
		{
			ulong tmpip;
			printf("No DHCP after timeout or manual IP address configured, switching to static IP address (%s)!\n", getenv("rcvrip"));
			tmpip = getenv_IPaddr ("rcvrip");
			NetCopyIP(&NetOurIP, &tmpip);
			sprintf(ip, "static");
		}

		/* Perform the recovery */
		printf("Starting retrieval of recovery image over network...\n");
		if ((imagSize = NetLoop(RCVR)) == -1)
		{
			printf("Failed\n");
			return;
		}
	}

	switch (mvBoardIdGet())
	{
		case RD_88F6510_SFU_ID:
		case RD_88F6560_GW_ID:
		case DB_88F6535_BP_ID:
			setenv("bootcmd","setenv bootargs ${console} ubi.mtd=2 root=ubi0:rootfsU rootfstype=ubifs ${mvNetConfig} ${mvPhoneConfig}; nand read.e ${loadaddr} 0x200000 0x400000; bootm ${loadaddr};");
			setenv("console","console=ttyS0,115200");
			saveenv();
		break;
	}

	printf("\nPermanent bootcmd: %s\n", getenv("bootcmd"));
	printf("\nPermanent console: %s\n", getenv("console"));

	/* This assignment to cmd should execute prior to the RD setenv and saveenv below*/
	sprintf(cmd,"setenv bootargs ${console} root=/dev/ram0 ${mvNetConfig} recovery=%s rcvrip=%s:%s%s  ethact=${ethact} ethaddr=%s eth1addr=%s; bootm ${loadaddr};", ip, getenv("rcvrip"), getenv("serverip"), getenv("bootargs_end"), getenv("ethaddr"), getenv("eth1addr"));
	setenv("bootcmd", cmd);
	printf("\nRecovery bootcmd: %s\n", cmd);

	printf("Booting recovery image at: [%s]...\n", getenv("loadaddr"));
	sprintf(cmd, "boot");
	sprintf(img, "%s", getenv("loadaddr"));
	argv[0] = cmd;
	argv[1] = img;

	do_bootd(NULL, 0, 2, argv);
}