/*-----------------------------------------------------------------------
 * List all images found in flash.
 */
int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	flash_info_t *info;
	int i, j;
	image_header_t *hdr;
	ulong data, len, checksum;

	for (i=0, info=&flash_info[0]; i<CFG_MAX_FLASH_BANKS; ++i, ++info) {
		if (info->flash_id == FLASH_UNKNOWN)
		goto next_bank;
		for (j=0; j<info->sector_count; ++j) {

			if (!(hdr=(image_header_t *)info->start[j]) ||
					(ntohl(hdr->ih_magic) != IH_MAGIC))
			goto next_sector;

			/* Copy header so we can blank CRC field for re-calculation */
			memmove (&header, (char *)hdr, sizeof(image_header_t));

			checksum = ntohl(header.ih_hcrc);
			header.ih_hcrc = 0;

			if (crc32 (0, (uchar *)&header, sizeof(image_header_t))
					!= checksum)
			goto next_sector;

			printf ("Image at %08lX:\n", (ulong)hdr);
			print_image_hdr( hdr );

			data = (ulong)hdr + sizeof(image_header_t);
			len = ntohl(hdr->ih_size);

			puts ("   Verifying Checksum ... ");
			if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {
				puts ("   Bad Data CRC\n");
			}
			puts ("OK\n");
			next_sector:;
		}
		next_bank:;
	}

	return (0);
}
static int image_info (ulong addr)
{
	ulong data, len, checksum;
	image_header_t *hdr = &header;

	printf ("\n## Checking Image at %08lx ...\n", addr);

	/* Copy header so we can blank CRC field for re-calculation */
	memmove (&header, (char *)addr, sizeof(image_header_t));

	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
		puts ("   Bad Magic Number\n");
		return 1;
	}

	data = (ulong)&header;
	len = sizeof(image_header_t);

	checksum = ntohl(hdr->ih_hcrc);
	hdr->ih_hcrc = 0;

	if (crc32 (0, (uchar *)data, len) != checksum) {
		puts ("   Bad Header Checksum\n");
		return 1;
	}

	/* for multi-file images we need the data part, too */
	print_image_hdr ((image_header_t *)addr);

	data = addr + sizeof(image_header_t);
	len = ntohl(hdr->ih_size);

	puts ("   Verifying Checksum ... ");
	if (crc32 (0, (uchar *)data, len) != ntohl(hdr->ih_dcrc)) {
		puts ("   Bad Data CRC\n");
		return 1;
	}
	puts ("OK\n");
	return 0;
}
예제 #3
0
static int image_info(ulong addr){
	ulong data, len, checksum;
	image_header_t *hdr = &header;

	printf("\nChecking image at 0x%08lX...\n", addr);

	/* Copy header so we can blank CRC field for re-calculation */
	memmove(&header, (char *)addr, sizeof(image_header_t));

	data = (ulong)&header;
	len  = sizeof(image_header_t);

	checksum = ntohl(hdr->ih_hcrc);
	hdr->ih_hcrc = 0;

	if(tinf_crc32((uchar *)data, len) != checksum){
		puts("## Error: bad header checksum!\n");
		return 1;
	}

	/* for multi-file images we need the data part, too */
	print_image_hdr((image_header_t *)addr);

	data = addr + sizeof(image_header_t);
	len  = ntohl(hdr->ih_size);

	puts("   Verifying checksum... ");

	if(tinf_crc32((uchar *)data, len) != ntohl(hdr->ih_dcrc)){
		puts("bad data CRC!\n");
		return(1);
	}

	puts("OK!\n\n");

	return(0);
}
void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
		     ulong addr, ulong *len_ptr, int verify)
{
	ulong len = 0, checksum;
	ulong initrd_start, initrd_end;
	ulong data;
	void (*theKernel)(int zero, int arch, uint params);
	image_header_t *hdr = &header;
	bd_t *bd = gd->bd;

#ifdef CONFIG_CMDLINE_TAG
	char *commandline = getenv ("bootargs");
#endif

	theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);

	/*
	 * Check if there is an initrd image
	 */
	if (argc >= 3) {
		SHOW_BOOT_PROGRESS (9);

		addr = simple_strtoul (argv[2], NULL, 16);

		printf ("## Loading Ramdisk Image at %08lx ...\n", addr);

		/* Copy header so we can blank CRC field for re-calculation */
#ifdef CONFIG_HAS_DATAFLASH
		if (addr_dataflash (addr)) {
			read_dataflash (addr, sizeof (image_header_t),
					(char *) &header);
		} else
#endif
			memcpy (&header, (char *) addr,
				sizeof (image_header_t));

		if (ntohl (hdr->ih_magic) != IH_MAGIC) {
			printf ("Bad Magic Number\n");
			SHOW_BOOT_PROGRESS (-10);
			do_reset (cmdtp, flag, argc, argv);
		}

		data = (ulong) & header;
		len = sizeof (image_header_t);

		checksum = ntohl (hdr->ih_hcrc);
		hdr->ih_hcrc = 0;

		if (crc32 (0, (unsigned char *) data, len) != checksum) {
			printf ("Bad Header Checksum\n");
			SHOW_BOOT_PROGRESS (-11);
			do_reset (cmdtp, flag, argc, argv);
		}

		SHOW_BOOT_PROGRESS (10);

		print_image_hdr (hdr);

		data = addr + sizeof (image_header_t);
		len = ntohl (hdr->ih_size);

#ifdef CONFIG_HAS_DATAFLASH
		if (addr_dataflash (addr)) {
			read_dataflash (data, len, (char *) CFG_LOAD_ADDR);
			data = CFG_LOAD_ADDR;
		}
#endif

		if (verify) {
			ulong csum = 0;

			printf ("   Verifying Checksum ... ");
			csum = crc32 (0, (unsigned char *) data, len);
			if (csum != ntohl (hdr->ih_dcrc)) {
				printf ("Bad Data CRC\n");
				SHOW_BOOT_PROGRESS (-12);
				do_reset (cmdtp, flag, argc, argv);
			}
			printf ("OK\n");
		}

		SHOW_BOOT_PROGRESS (11);

		if ((hdr->ih_os != IH_OS_LINUX) ||
		    (hdr->ih_arch != IH_CPU_ARM) ||
		    (hdr->ih_type != IH_TYPE_RAMDISK)) {
			printf ("No Linux ARM Ramdisk Image\n");
			SHOW_BOOT_PROGRESS (-13);
			do_reset (cmdtp, flag, argc, argv);
		}

#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)
		/*
		 *we need to copy the ramdisk to SRAM to let Linux boot
		 */
		memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len);
		data = ntohl(hdr->ih_load);
#endif /* CONFIG_B2 || CONFIG_EVB4510 */

		/*
		 * Now check if we have a multifile image
		 */
	} else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
		ulong tail = ntohl (len_ptr[0]) % 4;
		int i;

		SHOW_BOOT_PROGRESS (13);

		/* skip kernel length and terminator */
		data = (ulong) (&len_ptr[2]);
		/* skip any additional image length fields */
		for (i = 1; len_ptr[i]; ++i)
			data += 4;
		/* add kernel length, and align */
		data += ntohl (len_ptr[0]);
		if (tail) {
			data += 4 - tail;
		}

		len = ntohl (len_ptr[1]);

	} else {
		/*
		 * no initrd image
		 */
		SHOW_BOOT_PROGRESS (14);

		len = data = 0;
	}

#ifdef	DEBUG
	if (!data) {
		printf ("No initrd\n");
	}
#endif

	if (data) {
		initrd_start = data;
		initrd_end = initrd_start + len;
	} else {
		initrd_start = 0;
		initrd_end = 0;
	}

	SHOW_BOOT_PROGRESS (15);

	debug ("## Transferring control to Linux (at address %08lx) ...\n",
	       (ulong) theKernel);

#if defined (CONFIG_SETUP_MEMORY_TAGS) || \
    defined (CONFIG_CMDLINE_TAG) || \
    defined (CONFIG_INITRD_TAG) || \
    defined (CONFIG_SERIAL_TAG) || \
    defined (CONFIG_REVISION_TAG) || \
    defined (CONFIG_LCD) || \
    defined (CONFIG_VFD)
	setup_start_tag (bd);
#ifdef CONFIG_SERIAL_TAG
	setup_serial_tag (&params);
#endif
#ifdef CONFIG_REVISION_TAG
	setup_revision_tag (&params);
#endif
#ifdef CONFIG_SETUP_MEMORY_TAGS
	setup_memory_tags (bd);
#endif
#ifdef CONFIG_CMDLINE_TAG
	setup_commandline_tag (bd, commandline);
#endif
#ifdef CONFIG_INITRD_TAG
	if (initrd_start && initrd_end)
		setup_initrd_tag (bd, initrd_start, initrd_end);
#endif
#if defined (CONFIG_VFD) || defined (CONFIG_LCD)
	setup_videolfb_tag ((gd_t *) gd);
#endif
	setup_modelid_tag(&params);
	setup_cpuid_tag(&params);
	setup_end_tag (bd);
#endif

	/* we assume that the kernel is in place */
	printf ("\nStarting kernel ...\n\n");

#ifdef CONFIG_USB_DEVICE
	{
		extern void udc_disconnect (void);
		udc_disconnect ();
	}
#endif

	cleanup_before_linux ();

	theKernel (0, bd->bi_arch_number, bd->bi_boot_params);
}
예제 #5
0
int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){
	ulong addr, data, len;
	uint unc_len = CFG_BOOTM_LEN;
	int i;
	image_header_t *hdr = &header;
#ifdef CONFIG_TPLINK_IMAGE_HEADER
	tplink_image_header_t *fileTag;
#endif

	if(argc < 2){
		addr = load_addr;
	} else {
		addr = simple_strtoul(argv[1], NULL, 16);
	}

	printf("Booting image at: 0x%08lX\n", addr);

#ifndef CONFIG_TPLINK_IMAGE_HEADER
	memmove(&header, (char *)addr, sizeof(image_header_t));
	print_image_hdr(hdr);

	data = addr + sizeof(image_header_t);
#else
	fileTag = (tplink_image_header_t *)addr;
	print_image_hdr(fileTag);

	fake_image_header(hdr, fileTag);

	data = addr + TAG_LEN;
#endif /* !CONFIG_TPLINK_IMAGE_HEADER */

	len = ntohl(hdr->ih_size);

	/*
	 * We have reached the point of no return: we are going to
	 * overwrite all exception vector code, so we cannot easily
	 * recover from any failures any more...
	 */
#ifdef CONFIG_NETCONSOLE
	/*
	* Stop the ethernet stack if NetConsole could have
	* left it up
	*/
	eth_halt();
#endif

	/* TODO: should we flush caches for kernel? */
	/*
	 * Flush everything, restore caches for linux
	 */
	//mips_cache_flush();
	//mips_icache_flush_ix();

	/* XXX - this causes problems when booting from flash */
	/* dcache_disable(); */

	/*	case IH_COMP_LZMA:*/
	puts("Uncompressing kernel image... ");

	i = lzma_inflate((unsigned char *)data, len, (unsigned char*)ntohl(hdr->ih_load), (int *)&unc_len);

	if(i != LZMA_RESULT_OK){
		printf("## Error: LZMA error num: %d\n", i);
		return(-1);
	}

	puts("OK!\n");

#ifdef CONFIG_SILENT_CONSOLE
	fixup_silent_linux();
#endif

	do_bootm_linux(cmdtp, flag, argc, argv);

#ifdef DEBUG
	puts("\n## Error: control returned to monitor - resetting...\n");
	do_reset(cmdtp, flag, argc, argv);
#endif

	return(1);
}
예제 #6
0
int check_trx(int mode)
{
	ulong addr;
	ulong data, len, checksum;
    int verify;
    char *s;
	image_header_t *hdr = &header;
	
	s = getenv("verify");
	verify = (s && (*s == 'n')) ? 0 : 1;
	
	if (mode == 0)
		addr = CFG_FLASH_BASE + 0x50000;
	else
		addr = load_addr;
	
//	printf("## Booting image at %08lx ...\n", addr);
	printf("## Checking image at %08lx ...\n", addr);
	
	/* Copy header so we can blank CRC field for re-calculation */
#ifdef CONFIG_HAS_DATAFLASH
	if (addr_dataflash(addr))
	{
		read_dataflash(addr, sizeof(image_header_t), (char *)&header);
	} 
#endif
#if defined (CFG_ENV_IS_IN_NAND)
	if (addr >= CFG_FLASH_BASE)
		ranand_read(&header, (char *)(addr - CFG_FLASH_BASE), sizeof(image_header_t));
	else
		memmove (&header, (char *)addr, sizeof(image_header_t));
#elif defined (CFG_ENV_IS_IN_SPI)
	if (addr >= CFG_FLASH_BASE)
		raspi_read(&header, (char *)(addr - CFG_FLASH_BASE), sizeof(image_header_t));
	else
		memmove (&header, (char *)addr, sizeof(image_header_t));
#else //CFG_ENV_IS_IN_FLASH
	memmove (&header, (char *)addr, sizeof(image_header_t));
#endif //CFG_ENV_IS_IN_FLASH
	
	if (ntohl(hdr->ih_magic) != IH_MAGIC)
	{
		printf("Bad Magic Number,%08X \n", ntohl(hdr->ih_magic));
		return 1;
	}
//	else
//		printf("Magic Number: %08X, OK\n", ntohl(hdr->ih_magic));
	
	data = (ulong)&header;
	len  = sizeof(image_header_t);
	
	checksum = ntohl(hdr->ih_hcrc);
	hdr->ih_hcrc = 0;
	
	if (crc32(0, (char *)data, len) != checksum)
	{
		puts("Bad Header Checksum\n");
		return 1; 
	}
//	else
//		puts("Header Checksum OK\n");
	
	/* for multi-file images we need the data part, too */
	print_image_hdr((image_header_t *)hdr);
	
	data = addr + sizeof(image_header_t);
	len  = ntohl(hdr->ih_size);
	
#ifdef CONFIG_HAS_DATAFLASH
	if (addr_dataflash(addr))
	{
		read_dataflash(data, len, (char *)CFG_LOAD_ADDR);
		data = CFG_LOAD_ADDR;
	}
#endif
	
#if defined (CFG_ENV_IS_IN_NAND)
	if (addr >= CFG_FLASH_BASE) {
		ulong load_addr = CFG_SPINAND_LOAD_ADDR;
		ranand_read(load_addr, data - CFG_FLASH_BASE, len);
		data = load_addr;
	}
#elif defined (CFG_ENV_IS_IN_SPI)
	if (addr >= CFG_FLASH_BASE) {
		ulong load_addr = CFG_SPINAND_LOAD_ADDR;
		raspi_read(load_addr, data - CFG_FLASH_BASE, len);
		data = load_addr;
	}
#else //CFG_ENV_IS_IN_FLASH
#endif

	if (verify) 
	{
		puts("   Verifying Checksum ... ");
		if (crc32(0, (char *)data, len) != ntohl(hdr->ih_dcrc)) 
		{
			printf("Bad Data CRC\n");
			return 1;
		}
//		puts("Data CRC OK\n");
	}
	return 0;			
}
예제 #7
0
/******************************************************************************
 * scsi boot command intepreter. Derived from diskboot
 */
int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	char *boot_device = NULL;
	char *ep;
	int dev, part = 0;
	ulong addr, cnt, checksum;
	disk_partition_t info;
	image_header_t *hdr;
	int rcode = 0;

	switch (argc) {
	case 1:
		addr = CFG_LOAD_ADDR;
		boot_device = getenv ("bootdevice");
		break;
	case 2:
		addr = simple_strtoul(argv[1], NULL, 16);
		boot_device = getenv ("bootdevice");
		break;
	case 3:
		addr = simple_strtoul(argv[1], NULL, 16);
		boot_device = argv[2];
		break;
	default:
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	if (!boot_device) {
		puts ("\n** No boot device **\n");
		return 1;
	}

	dev = simple_strtoul(boot_device, &ep, 16);
	printf("booting from dev %d\n",dev);
	if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
		printf ("\n** Device %d not available\n", dev);
		return 1;
	}

	if (*ep) {
		if (*ep != ':') {
			puts ("\n** Invalid boot device, use `dev[:part]' **\n");
			return 1;
		}
		part = simple_strtoul(++ep, NULL, 16);
	}
	if (get_partition_info (&scsi_dev_desc[dev], part, &info)) {
		printf("error reading partinfo\n");
		return 1;
	}
	if ((strncmp((char *)(info.type), BOOT_PART_TYPE, sizeof(info.type)) != 0) &&
	    (strncmp((char *)(info.type), BOOT_PART_COMP, sizeof(info.type)) != 0)) {
		printf ("\n** Invalid partition type \"%.32s\""
			" (expect \"" BOOT_PART_TYPE "\")\n",
			info.type);
		return 1;
	}

	printf ("\nLoading from SCSI device %d, partition %d: "
		"Name: %.32s  Type: %.32s\n",
		dev, part, info.name, info.type);

	debug ("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n",
		info.start, info.size, info.blksz);

	if (scsi_read (dev, info.start, 1, (ulong *)addr) != 1) {
		printf ("** Read error on %d:%d\n", dev, part);
		return 1;
	}

	hdr = (image_header_t *)addr;

	if (ntohl(hdr->ih_magic) == IH_MAGIC) {
		printf("\n** Bad Magic Number **\n");
		return 1;
	}

	checksum = ntohl(hdr->ih_hcrc);
	hdr->ih_hcrc = 0;

	if (crc32 (0, (uchar *)hdr, sizeof(image_header_t)) != checksum) {
		puts ("\n** Bad Header Checksum **\n");
		return 1;
	}
	hdr->ih_hcrc = htonl(checksum);	/* restore checksum for later use */

	print_image_hdr (hdr);
	cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
	cnt += info.blksz - 1;
	cnt /= info.blksz;
	cnt -= 1;

	if (scsi_read (dev, info.start+1, cnt,
		      (ulong *)(addr+info.blksz)) != cnt) {
		printf ("** Read error on %d:%d\n", dev, part);
		return 1;
	}
	/* Loading ok, update default load address */
	load_addr = addr;

	flush_cache (addr, (cnt+1)*info.blksz);

	/* Check if we should attempt an auto-start */
	if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
		char *local_args[2];
		extern int do_bootm (cmd_tbl_t *, int, int, char *[]);
		local_args[0] = argv[0];
		local_args[1] = NULL;
		printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);
		rcode = do_bootm (cmdtp, 0, 1, local_args);
	}
	 return rcode;
}
예제 #8
0
int do_docboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	char *boot_device = NULL;
	char *ep;
	int dev;
	ulong cnt;
	ulong addr;
	ulong offset = 0;
	image_header_t *hdr;
	int rcode = 0;

	switch (argc) {
	case 1:
		addr = CFG_LOAD_ADDR;
		boot_device = getenv ("bootdevice");
		break;
	case 2:
		addr = simple_strtoul(argv[1], NULL, 16);
		boot_device = getenv ("bootdevice");
		break;
	case 3:
		addr = simple_strtoul(argv[1], NULL, 16);
		boot_device = argv[2];
		break;
	case 4:
		addr = simple_strtoul(argv[1], NULL, 16);
		boot_device = argv[2];
		offset = simple_strtoul(argv[3], NULL, 16);
		break;
	default:
		printf ("Usage:\n%s\n", cmdtp->usage);
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}

	if (!boot_device) {
		puts ("\n** No boot device **\n");
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}

	dev = simple_strtoul(boot_device, &ep, 16);

	if ((dev >= CFG_MAX_DOC_DEVICE) ||
	    (doc_dev_desc[dev].ChipID == DOC_ChipID_UNKNOWN)) {
		printf ("\n** Device %d not available\n", dev);
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}

	printf ("\nLoading from device %d: %s at 0x%lX (offset 0x%lX)\n",
		dev, doc_dev_desc[dev].name, doc_dev_desc[dev].physadr,
		offset);

	if (doc_rw (doc_dev_desc + dev, 1, offset,
		    SECTORSIZE, NULL, (u_char *)addr)) {
		printf ("** Read error on %d\n", dev);
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}

	hdr = (image_header_t *)addr;

	if (hdr->ih_magic == IH_MAGIC) {

		print_image_hdr (hdr);

		cnt = (ntohl(hdr->ih_size) + sizeof(image_header_t));
		cnt -= SECTORSIZE;
	} else {
		puts ("\n** Bad Magic Number **\n");
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}

	if (doc_rw (doc_dev_desc + dev, 1, offset + SECTORSIZE, cnt,
		    NULL, (u_char *)(addr+SECTORSIZE))) {
		printf ("** Read error on %d\n", dev);
		SHOW_BOOT_PROGRESS (-1);
		return 1;
	}

	/* Loading ok, update default load address */

	load_addr = addr;

	/* Check if we should attempt an auto-start */
	if (((ep = getenv("autostart")) != NULL) && (strcmp(ep,"yes") == 0)) {
		char *local_args[2];
		extern int do_bootm (cmd_tbl_t *, int, int, char *[]);

		local_args[0] = argv[0];
		local_args[1] = NULL;

		printf ("Automatic boot of image at addr 0x%08lX ...\n", addr);

		do_bootm (cmdtp, 0, 1, local_args);
		rcode = 1;
	}
	return rcode;
}
void do_bootm_linux(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],
		    unsigned long addr, unsigned long *len_ptr, int verify)
{
	unsigned long data, len = 0;
	unsigned long initrd_start, initrd_end;
	unsigned long image_start, image_end;
	unsigned long checksum;
	void (*theKernel)(int magic, void *tagtable);
	image_header_t *hdr;
	struct tag *params, *params_start;
	char *commandline = getenv("bootargs");

	hdr = (image_header_t *)addr;
	image_start = addr;
	image_end = addr + hdr->ih_size;

	theKernel = (void *)ntohl(hdr->ih_ep);

	/*
	 * Check if there is an initrd image
	 */
	if (argc >= 3) {
		show_boot_progress (9);

		addr = simple_strtoul(argv[2], NULL, 16);

		printf("## Loading RAMDISK image at %08lx ...\n", addr);

		memcpy(&header, (char *)addr, sizeof(header));
		hdr = &header;

		if (ntohl(hdr->ih_magic) != IH_MAGIC) {
			puts("Bad Magic Number\n");
			show_boot_progress (-10);
			do_reset(cmdtp, flag, argc, argv);
		}

		data = (unsigned long)hdr;
		len = sizeof(*hdr);
		checksum = ntohl(hdr->ih_hcrc);
		hdr->ih_hcrc = 0;

		if (crc32(0, (unsigned char *)data, len) != checksum) {
			puts("Bad Header Checksum\n");
			show_boot_progress (-11);
			do_reset(cmdtp, flag, argc, argv);
		}

		show_boot_progress (10);

		print_image_hdr(hdr);

		data = addr + sizeof(header);
		len = ntohl(hdr->ih_size);

		if (verify) {
			unsigned long csum = 0;

			puts("   Verifying Checksum ... ");
			csum = crc32(0, (unsigned char *)data, len);
			if (csum != ntohl(hdr->ih_dcrc)) {
				puts("Bad Data CRC\n");
				show_boot_progress (-12);
				do_reset(cmdtp, flag, argc, argv);
			}
			puts("OK\n");
		}

		show_boot_progress (11);

		if ((hdr->ih_os != IH_OS_LINUX) ||
		    (hdr->ih_arch != IH_CPU_AVR32) ||
		    (hdr->ih_type != IH_TYPE_RAMDISK)) {
			puts("Not a Linux/AVR32 RAMDISK image\n");
			show_boot_progress (-13);
			do_reset(cmdtp, flag, argc, argv);
		}
	} else if ((hdr->ih_type == IH_TYPE_MULTI) && (len_ptr[1])) {
		ulong tail = ntohl (len_ptr[0]) % 4;
		int i;

		show_boot_progress (13);

		/* skip kernel length and terminator */
		data = (ulong) (&len_ptr[2]);
		/* skip any additional image length fields */
		for (i = 1; len_ptr[i]; ++i)
			data += 4;
		/* add kernel length, and align */
		data += ntohl (len_ptr[0]);
		if (tail) {
			data += 4 - tail;
		}

		len = ntohl (len_ptr[1]);
	} else {
		/* no initrd image */
		show_boot_progress (14);
		len = data = 0;
	}

	if (data) {
		initrd_start = data;
		initrd_end = initrd_start + len;
	} else {
		initrd_start = 0;
		initrd_end = 0;
	}

	show_boot_progress (15);

	params = params_start = (struct tag *)gd->bd->bi_boot_params;
	params = setup_start_tag(params);
	params = setup_memory_tags(params);
	if (initrd_start) {
		params = setup_ramdisk_tag(params,
					   PHYSADDR(initrd_start),
					   PHYSADDR(initrd_end));
	}
	params = setup_commandline_tag(params, commandline);
	params = setup_clock_tags(params);
	params = setup_ethernet_tags(params);
	setup_end_tag(params);

	printf("\nStarting kernel at %p (params at %p)...\n\n",
	       theKernel, params_start);

	prepare_to_boot();

	theKernel(ATAG_MAGIC, params_start);
}