コード例 #1
0
ファイル: cmd_bootm.c プロジェクト: kontar/u-boot
static int fit_check_kernel(const void *fit, int os_noffset, int verify)
{
	fit_image_print(fit, os_noffset, "   ");

	if (verify) {
		puts("   Verifying Hash Integrity ... ");
		if (!fit_image_verify(fit, os_noffset)) {
			puts("Bad Data Hash\n");
			bootstage_error(BOOTSTAGE_ID_FIT_CHECK_HASH);
			return 0;
		}
		puts("OK\n");
	}
	bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_ARCH);

	if (!fit_image_check_target_arch(fit, os_noffset)) {
		puts("Unsupported Architecture\n");
		bootstage_error(BOOTSTAGE_ID_FIT_CHECK_ARCH);
		return 0;
	}

	bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_KERNEL);
	if (!fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL) &&
	    !fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL_NOLOAD)) {
		puts("Not a kernel image\n");
		bootstage_error(BOOTSTAGE_ID_FIT_CHECK_KERNEL);
		return 0;
	}

	bootstage_mark(BOOTSTAGE_ID_FIT_CHECKED);
	return 1;
}
コード例 #2
0
ファイル: cmd_bootm.c プロジェクト: kontar/u-boot
static int do_bootm_rtems(int flag, int argc, char * const argv[],
			   bootm_headers_t *images)
{
	void (*entry_point)(bd_t *);

	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
		return 1;

#if defined(CONFIG_FIT)
	if (!images->legacy_hdr_valid) {
		fit_unsupported_reset("RTEMS");
		return 1;
	}
#endif

	entry_point = (void (*)(bd_t *))images->ep;

	printf("## Transferring control to RTEMS (at address %08lx) ...\n",
		(ulong)entry_point);

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

	/*
	 * RTEMS Parameters:
	 *   r3: ptr to board info data
	 */
	(*entry_point)(gd->bd);

	return 1;
}
コード例 #3
0
ファイル: cmd_bootm.c プロジェクト: kontar/u-boot
static int do_bootm_integrity(int flag, int argc, char * const argv[],
			   bootm_headers_t *images)
{
	void (*entry_point)(void);

	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
		return 1;

#if defined(CONFIG_FIT)
	if (!images->legacy_hdr_valid) {
		fit_unsupported_reset("INTEGRITY");
		return 1;
	}
#endif

	entry_point = (void (*)(void))images->ep;

	printf("## Transferring control to INTEGRITY (at address %08lx) ...\n",
		(ulong)entry_point);

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

	/*
	 * INTEGRITY Parameters:
	 *   None
	 */
	(*entry_point)();

	return 1;
}
コード例 #4
0
ファイル: mv_common.c プロジェクト: Android4SAM/u-boot-at91
int mv_load_fpga(void)
{
	int result;
	size_t data_size = 0;
	void *fpga_data = NULL;
	char *datastr = getenv("fpgadata");
	char *sizestr = getenv("fpgadatasize");

	if (getenv("skip_fpga")) {
		printf("found 'skip_fpga' -> FPGA _not_ loaded !\n");
		return -1;
	}
	printf("loading FPGA\n");

	if (datastr)
		fpga_data = (void *)simple_strtoul(datastr, NULL, 16);
	if (sizestr)
		data_size = (size_t)simple_strtoul(sizestr, NULL, 16);
	if (!data_size) {
		printf("fpgadatasize invalid -> FPGA _not_ loaded !\n");
		return -1;
	}

	result = fpga_load(0, fpga_data, data_size, BIT_FULL);
	if (!result)
		bootstage_mark(BOOTSTAGE_ID_START);

	return result;
}
コード例 #5
0
ファイル: eth.c プロジェクト: KaijiHakaroku/u-boot
static void eth_common_init(void)
{
	bootstage_mark(BOOTSTAGE_ID_NET_ETH_START);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
	miiphy_init();
#endif

#ifdef CONFIG_PHYLIB
	phy_init();
#endif

	/*
	 * If board-specific initialization exists, call it.
	 * If not, call a CPU-specific one
	 */
	if (board_eth_init != __def_eth_init) {
		if (board_eth_init(gd->bd) < 0)
			printf("Board Net Initialization Failed\n");
	} else if (cpu_eth_init != __def_eth_init) {
		if (cpu_eth_init(gd->bd) < 0)
			printf("CPU Net Initialization Failed\n");
	} else {
#ifndef CONFIG_DM_ETH
		printf("Net Initialization Skipped\n");
#endif
	}
}
コード例 #6
0
ファイル: bootm.c プロジェクト: PlanetEater/uboot-nsa320
static int bootm_load_os(bootm_headers_t *images, int boot_progress)
{
	image_info_t os = images->os;
	ulong load = os.load;
	ulong load_end;
	ulong blob_start = os.start;
	ulong blob_end = os.end;
	ulong image_start = os.image_start;
	ulong image_len = os.image_len;
	ulong flush_start = ALIGN_DOWN(load, ARCH_DMA_MINALIGN);
	ulong flush_len;
	bool no_overlap;
	void *load_buf, *image_buf;
	int err;

	load_buf = map_sysmem(load, 0);
	image_buf = map_sysmem(os.image_start, image_len);
	err = bootm_decomp_image(os.comp, load, os.image_start, os.type,
				 load_buf, image_buf, image_len,
				 CONFIG_SYS_BOOTM_LEN, &load_end);
	if (err) {
		bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
		return err;
	}

	flush_len = load_end - load;
	if (flush_start < load)
		flush_len += load - flush_start;

	flush_cache(flush_start, ALIGN(flush_len, ARCH_DMA_MINALIGN));

	debug("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, load_end);
	bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);

	no_overlap = (os.comp == IH_COMP_NONE && load == image_start);

	if (!no_overlap && load < blob_end && load_end > blob_start) {
		debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
		      blob_start, blob_end);
		debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
		      load_end);

		/* Check what type of image this is. */
		if (images->legacy_hdr_valid) {
			if (image_get_type(&images->legacy_hdr_os_copy)
					== IH_TYPE_MULTI)
				puts("WARNING: legacy format multi component image overwritten\n");
			return BOOTM_ERR_OVERLAP;
		} else {
			puts("ERROR: new format image overwritten - must RESET the board to recover\n");
			bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
			return BOOTM_ERR_RESET;
		}
	}

	lmb_reserve(&images->lmb, images->os.load, (load_end -
						    images->os.load));
	return 0;
}
コード例 #7
0
ファイル: image.c プロジェクト: Android4SAM/u-boot-at91
/**
 * image_get_ramdisk - get and verify ramdisk image
 * @rd_addr: ramdisk image start address
 * @arch: expected ramdisk architecture
 * @verify: checksum verification flag
 *
 * image_get_ramdisk() returns a pointer to the verified ramdisk image
 * header. Routine receives image start address and expected architecture
 * flag. Verification done covers data and header integrity and os/type/arch
 * fields checking.
 *
 * If dataflash support is enabled routine checks for dataflash addresses
 * and handles required dataflash reads.
 *
 * returns:
 *     pointer to a ramdisk image header, if image was found and valid
 *     otherwise, return NULL
 */
static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch,
						int verify)
{
	const image_header_t *rd_hdr = (const image_header_t *)rd_addr;

	if (!image_check_magic(rd_hdr)) {
		puts("Bad Magic Number\n");
		bootstage_error(BOOTSTAGE_ID_RD_MAGIC);
		return NULL;
	}

	if (!image_check_hcrc(rd_hdr)) {
		puts("Bad Header Checksum\n");
		bootstage_error(BOOTSTAGE_ID_RD_HDR_CHECKSUM);
		return NULL;
	}

	bootstage_mark(BOOTSTAGE_ID_RD_MAGIC);
	image_print_contents(rd_hdr);

	if (verify) {
		puts("   Verifying Checksum ... ");
		if (!image_check_dcrc(rd_hdr)) {
			puts("Bad Data CRC\n");
			bootstage_error(BOOTSTAGE_ID_RD_CHECKSUM);
			return NULL;
		}
		puts("OK\n");
	}

	bootstage_mark(BOOTSTAGE_ID_RD_HDR_CHECKSUM);

	if (!image_check_os(rd_hdr, IH_OS_LINUX) ||
	    !image_check_arch(rd_hdr, arch) ||
	    !image_check_type(rd_hdr, IH_TYPE_RAMDISK)) {
		printf("No Linux %s Ramdisk Image\n",
				genimg_get_arch_name(arch));
		bootstage_error(BOOTSTAGE_ID_RAMDISK);
		return NULL;
	}

	return rd_hdr;
}
コード例 #8
0
ファイル: bootm.c プロジェクト: CogSystems/u-boot
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
{
	if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
		bootstage_mark(BOOTSTAGE_ID_RUN_OS);
		printf("## Transferring control to Linux (at address %08lx)...\n",
		       images->ep);
		printf("sandbox: continuing, as we cannot run Linux\n");
	}

	return 0;
}
コード例 #9
0
ファイル: cmd_bootm.c プロジェクト: BuloZB/u-boot-imx
void do_bootvx_fdt(bootm_headers_t *images)
{
#if defined(CONFIG_OF_LIBFDT)
	int ret;
	char *bootline;
	ulong of_size = images->ft_len;
	char **of_flat_tree = &images->ft_addr;
	struct lmb *lmb = &images->lmb;

	if (*of_flat_tree) {
		boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree);

		ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);
		if (ret)
			return;

		ret = fdt_add_subnode(*of_flat_tree, 0, "chosen");
		if ((ret >= 0 || ret == -FDT_ERR_EXISTS)) {
			bootline = getenv("bootargs");
			if (bootline) {
				ret = fdt_find_and_setprop(*of_flat_tree,
						"/chosen", "bootargs",
						bootline,
						strlen(bootline) + 1, 1);
				if (ret < 0) {
					printf("## ERROR: %s : %s\n", __func__,
					       fdt_strerror(ret));
					return;
				}
			}
		} else {
			printf("## ERROR: %s : %s\n", __func__,
			       fdt_strerror(ret));
			return;
		}
	}
#endif

	boot_prep_vxworks(images);

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

#if defined(CONFIG_OF_LIBFDT)
	printf("## Starting vxWorks at 0x%08lx, device tree at 0x%08lx ...\n",
	       (ulong)images->ep, (ulong)*of_flat_tree);
#else
	printf("## Starting vxWorks at 0x%08lx\n", (ulong)images->ep);
#endif

	boot_jump_vxworks(images);

	puts("## vxWorks terminated\n");
}
コード例 #10
0
ファイル: bootm.c プロジェクト: Analias/SNOWLeo-SDR-1
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
{
	/* First parameter is mapped to $r5 for kernel boot args */
	void	(*theKernel) (char *, ulong, ulong);
	char	*commandline = getenv ("bootargs");
	ulong	rd_data_start, rd_data_end;

	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
		return 1;

	int	ret;

	char	*of_flat_tree = NULL;
#if defined(CONFIG_OF_LIBFDT)
	/* did generic code already find a device tree? */
	if (images->ft_len)
		of_flat_tree = images->ft_addr;
#endif

	theKernel = (void (*)(char *, ulong, ulong))images->ep;

	/* find ramdisk */
	ret = boot_get_ramdisk (argc, argv, images, IH_ARCH_MICROBLAZE,
			&rd_data_start, &rd_data_end);
	if (ret)
		return 1;

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

	if (!of_flat_tree && argc > 3)
		of_flat_tree = (char *)simple_strtoul(argv[3], NULL, 16);
#ifdef DEBUG
	printf ("## Transferring control to Linux (at address 0x%08lx) " \
				"ramdisk 0x%08lx, FDT 0x%08lx...\n",
		(ulong) theKernel, rd_data_start, (ulong) of_flat_tree);
#endif

#ifdef XILINX_USE_DCACHE
	flush_cache(0, XILINX_DCACHE_BYTE_SIZE);
#endif
	/*
	 * Linux Kernel Parameters (passing device tree):
	 * r5: pointer to command line
	 * r6: pointer to ramdisk
	 * r7: pointer to the fdt, followed by the board info data
	 */
	theKernel (commandline, rd_data_start, (ulong) of_flat_tree);
	/* does not return */

	return 1;
}
コード例 #11
0
ファイル: eth-uclass.c プロジェクト: SunnyBrother/u-boot-at91
int eth_initialize(void)
{
	int num_devices = 0;
	struct udevice *dev;

	eth_common_init();

	/*
	 * Devices need to write the hwaddr even if not started so that Linux
	 * will have access to the hwaddr that u-boot stored for the device.
	 * This is accomplished by attempting to probe each device and calling
	 * their write_hwaddr() operation.
	 */
	uclass_first_device(UCLASS_ETH, &dev);
	if (!dev) {
		printf("No ethernet found.\n");
		bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
	} else {
		char *ethprime = getenv("ethprime");
		struct udevice *prime_dev = NULL;

		if (ethprime)
			prime_dev = eth_get_dev_by_name(ethprime);
		if (prime_dev) {
			eth_set_dev(prime_dev);
			eth_current_changed();
		} else {
			eth_set_dev(NULL);
		}

		bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
		do {
			if (num_devices)
				printf(", ");

			printf("eth%d: %s", dev->seq, dev->name);

			if (ethprime && dev == prime_dev)
				printf(" [PRIME]");

			eth_write_hwaddr(dev);

			uclass_next_device(&dev);
			num_devices++;
		} while (dev);

		putc('\n');
	}

	return num_devices;
}
コード例 #12
0
ファイル: cmd_bootm.c プロジェクト: kontar/u-boot
/**
 * image_get_kernel - verify legacy format kernel image
 * @img_addr: in RAM address of the legacy format image to be verified
 * @verify: data CRC verification flag
 *
 * image_get_kernel() verifies legacy image integrity and returns pointer to
 * legacy image header if image verification was completed successfully.
 *
 * returns:
 *     pointer to a legacy image header if valid image was found
 *     otherwise return NULL
 */
static image_header_t *image_get_kernel(ulong img_addr, int verify)
{
	image_header_t *hdr = (image_header_t *)img_addr;

	if (!image_check_magic(hdr)) {
		puts("Bad Magic Number\n");
		bootstage_error(BOOTSTAGE_ID_CHECK_MAGIC);
		return NULL;
	}
	bootstage_mark(BOOTSTAGE_ID_CHECK_HEADER);

	if (!image_check_hcrc(hdr)) {
		puts("Bad Header Checksum\n");
		bootstage_error(BOOTSTAGE_ID_CHECK_HEADER);
		return NULL;
	}

	bootstage_mark(BOOTSTAGE_ID_CHECK_CHECKSUM);
	image_print_contents(hdr);

	if (verify) {
		puts("   Verifying Checksum ... ");
		if (!image_check_dcrc(hdr)) {
			printf("Bad Data CRC\n");
			bootstage_error(BOOTSTAGE_ID_CHECK_CHECKSUM);
			return NULL;
		}
		puts("OK\n");
	}
	bootstage_mark(BOOTSTAGE_ID_CHECK_ARCH);

	if (!image_check_target_arch(hdr)) {
		printf("Unsupported Architecture 0x%x\n", image_get_arch(hdr));
		bootstage_error(BOOTSTAGE_ID_CHECK_ARCH);
		return NULL;
	}
	return hdr;
}
コード例 #13
0
ファイル: bootm.c プロジェクト: danielschwierzeck/u-boot
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
{
	bd_t	*bd = gd->bd;
	char	*s;
	int	machid = bd->bi_arch_number;
	void	(*theKernel)(int arch, uint params);

	/*
	 * allow the PREP bootm subcommand, it is required for bootm to work
	 */
	if (flag & BOOTM_STATE_OS_PREP)
		return 0;

	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
		return 1;

	theKernel = (void (*)(int, uint))images->ep;

	s = env_get("machid");
	if (s) {
		machid = simple_strtoul(s, NULL, 16);
		printf("Using machid 0x%x from environment\n", machid);
	}

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

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

	if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
#ifdef CONFIG_OF_LIBFDT
		debug("using: FDT\n");
		if (image_setup_linux(images)) {
			printf("FDT creation failed! hanging...");
			hang();
		}
#endif
	}

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

	cleanup_before_linux();
	if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
		theKernel(machid, (unsigned long)images->ft_addr);

	/* does not return */

	return 1;
}
コード例 #14
0
int do_bootm_linux(int flag, int argc, char * const argv[],
			bootm_headers_t *images)
{
	void (*theKernel) (int, char **, char **, int *);
	char *bootargs = getenv("bootargs");
	char *start;
	uint len;

	/* find kernel entry point */
	theKernel = (void (*)(int, char **, char **, int *))images->ep;

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

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

	gd->bd->bi_boot_params = gd->bd->bi_memstart + (16 << 20) - 256;
	debug("%-12s= 0x%08lX\n", "boot_params", (ulong)gd->bd->bi_boot_params);

	/* set Magic */
	*(int32_t *)(gd->bd->bi_boot_params - 4) = 0x12345678;
	/* set ram_size */
	*(int32_t *)(gd->bd->bi_boot_params - 8) = gd->ram_size;

	start = (char *)gd->bd->bi_boot_params;

	len = strlen(bootargs);

	strncpy(start, bootargs, len + 1);

	start += len;

	len = images->rd_end - images->rd_start;
	if (len > 0) {
		start += sprintf(start, " rd_start=0x%08X rd_size=0x%0X",
		(uint) UNCACHED_SDRAM(images->rd_start),
		(uint) len);
	}

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

	theKernel(0, NULL, NULL, 0);

	/* does not return */
	return 1;
}
コード例 #15
0
ファイル: cmd_bootm.c プロジェクト: 0s4l/u-boot-xlnx
static int do_bootm_plan9(int flag, int argc, char * const argv[],
			   bootm_headers_t *images)
{
	void (*entry_point)(void);
	char *s;

	if (flag & BOOTM_STATE_OS_PREP)
		return 0;
	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
		return 1;

#if defined(CONFIG_FIT)
	if (!images->legacy_hdr_valid) {
		fit_unsupported_reset("Plan 9");
		return 1;
	}
#endif

	/* See README.plan9 */
	s = getenv("confaddr");
	if (s != NULL) {
		char *confaddr = (char *)simple_strtoul(s, NULL, 16);

		if (argc > 0) {
			copy_args(confaddr, argc, argv, '\n');
		} else {
			s = getenv("bootargs");
			if (s != NULL)
				strcpy(confaddr, s);
		}
	}

	entry_point = (void (*)(void))images->ep;

	printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
		(ulong)entry_point);

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

	/*
	 * Plan 9 Parameters:
	 *   None
	 */
	(*entry_point)();

	return 1;
}
コード例 #16
0
ファイル: bootm.c プロジェクト: gitabhi/bbone
static void boot_jump_linux(bootm_headers_t *images)
{
	void (*theKernel) (int, char **, char **, int *);

	/* find kernel entry point */
	theKernel = (void (*)(int, char **, char **, int *))images->ep;

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

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

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

	theKernel(linux_argc, linux_argv, linux_env, 0);
}
コード例 #17
0
ファイル: bootm.c プロジェクト: 0xFelix/u-boot-edminiv2
int do_bootm_linux(int flag, int argc, char * const argv[], bootm_headers_t *images)
{
	void	(*theKernel)(int magic, void *tagtable);
	struct	tag *params, *params_start;
	char	*commandline = getenv("bootargs");

	/*
	 * allow the PREP bootm subcommand, it is required for bootm to work
	 *
	 * TODO: Andreas Bießmann <*****@*****.**> refactor the
	 * do_bootm_linux() for avr32
	 */
	if (flag & BOOTM_STATE_OS_PREP)
		return 0;

	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
		return 1;

	theKernel = (void *)images->ep;

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

	params = params_start = (struct tag *)gd->bd->bi_boot_params;
	params = setup_start_tag(params);
	params = setup_memory_tags(params);
	if (images->rd_start) {
		params = setup_ramdisk_tag(params,
					   PHYSADDR(images->rd_start),
					   PHYSADDR(images->rd_end));
	}
	params = setup_commandline_tag(params, commandline);
	params = setup_clock_tags(params);
	params = setup_ethernet_tags(params);
	params = setup_boardinfo_tag(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);
	/* does not return */

	return 1;
}
コード例 #18
0
ファイル: bootm_os.c プロジェクト: CheezeCake/edison-u-boot
static int do_bootm_openrtos(int flag, int argc, char * const argv[],
			   bootm_headers_t *images)
{
	void (*entry_point)(void);

	if (flag != BOOTM_STATE_OS_GO)
		return 0;

	entry_point = (void (*)(void))images->ep;

	printf("## Transferring control to OpenRTOS (at address %08lx) ...\n",
		(ulong)entry_point);

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

	/*
	 * OpenRTOS Parameters:
	 *   None
	 */
	(*entry_point)();

	return 1;
}
コード例 #19
0
ファイル: cmd_bootm.c プロジェクト: kontar/u-boot
/**
 * boot_get_kernel - find kernel image
 * @os_data: pointer to a ulong variable, will hold os data start address
 * @os_len: pointer to a ulong variable, will hold os data length
 *
 * boot_get_kernel() tries to find a kernel image, verifies its integrity
 * and locates kernel data.
 *
 * returns:
 *     pointer to image header if valid image was found, plus kernel start
 *     address and length, otherwise NULL
 */
static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
		char * const argv[], bootm_headers_t *images, ulong *os_data,
		ulong *os_len)
{
	image_header_t	*hdr;
	ulong		img_addr;
	const void *buf;
#if defined(CONFIG_FIT)
	const void	*fit_hdr;
	const char	*fit_uname_config = NULL;
	const char	*fit_uname_kernel = NULL;
	const void	*data;
	size_t		len;
	int		cfg_noffset;
	int		os_noffset;
#endif

	/* find out kernel image address */
	if (argc < 2) {
		img_addr = load_addr;
		debug("*  kernel: default image load address = 0x%08lx\n",
				load_addr);
#if defined(CONFIG_FIT)
	} else if (fit_parse_conf(argv[1], load_addr, &img_addr,
							&fit_uname_config)) {
		debug("*  kernel: config '%s' from image at 0x%08lx\n",
				fit_uname_config, img_addr);
	} else if (fit_parse_subimage(argv[1], load_addr, &img_addr,
							&fit_uname_kernel)) {
		debug("*  kernel: subimage '%s' from image at 0x%08lx\n",
				fit_uname_kernel, img_addr);
#endif
	} else {
		img_addr = simple_strtoul(argv[1], NULL, 16);
		debug("*  kernel: cmdline image address = 0x%08lx\n", img_addr);
	}

	bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);

	/* copy from dataflash if needed */
	img_addr = genimg_get_image(img_addr);

	/* check image type, for FIT images get FIT kernel node */
	*os_data = *os_len = 0;
	buf = map_sysmem(img_addr, 0);
	switch (genimg_get_format(buf)) {
	case IMAGE_FORMAT_LEGACY:
		printf("## Booting kernel from Legacy Image at %08lx ...\n",
				img_addr);
		hdr = image_get_kernel(img_addr, images->verify);
		if (!hdr)
			return NULL;
		bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE);

		/* get os_data and os_len */
		switch (image_get_type(hdr)) {
		case IH_TYPE_KERNEL:
		case IH_TYPE_KERNEL_NOLOAD:
			*os_data = image_get_data(hdr);
			*os_len = image_get_data_size(hdr);
			break;
		case IH_TYPE_MULTI:
			image_multi_getimg(hdr, 0, os_data, os_len);
			break;
		case IH_TYPE_STANDALONE:
			*os_data = image_get_data(hdr);
			*os_len = image_get_data_size(hdr);
			break;
		default:
			printf("Wrong Image Type for %s command\n",
				cmdtp->name);
			bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
			return NULL;
		}

		/*
		 * copy image header to allow for image overwrites during
		 * kernel decompression.
		 */
		memmove(&images->legacy_hdr_os_copy, hdr,
			sizeof(image_header_t));

		/* save pointer to image header */
		images->legacy_hdr_os = hdr;

		images->legacy_hdr_valid = 1;
		bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
		break;
#if defined(CONFIG_FIT)
	case IMAGE_FORMAT_FIT:
		fit_hdr = buf;
		printf("## Booting kernel from FIT Image at %08lx ...\n",
				img_addr);

		if (!fit_check_format(fit_hdr)) {
			puts("Bad FIT kernel image format!\n");
			bootstage_error(BOOTSTAGE_ID_FIT_FORMAT);
			return NULL;
		}
		bootstage_mark(BOOTSTAGE_ID_FIT_FORMAT);

		if (!fit_uname_kernel) {
			/*
			 * no kernel image node unit name, try to get config
			 * node first. If config unit node name is NULL
			 * fit_conf_get_node() will try to find default config
			 * node
			 */
			bootstage_mark(BOOTSTAGE_ID_FIT_NO_UNIT_NAME);
#ifdef CONFIG_FIT_BEST_MATCH
			if (fit_uname_config)
				cfg_noffset =
					fit_conf_get_node(fit_hdr,
							  fit_uname_config);
			else
				cfg_noffset =
					fit_conf_find_compat(fit_hdr,
							     gd->fdt_blob);
#else
			cfg_noffset = fit_conf_get_node(fit_hdr,
							fit_uname_config);
#endif
			if (cfg_noffset < 0) {
				bootstage_error(BOOTSTAGE_ID_FIT_NO_UNIT_NAME);
				return NULL;
			}
			/* save configuration uname provided in the first
			 * bootm argument
			 */
			images->fit_uname_cfg = fdt_get_name(fit_hdr,
								cfg_noffset,
								NULL);
			printf("   Using '%s' configuration\n",
				images->fit_uname_cfg);
			bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);

			os_noffset = fit_conf_get_kernel_node(fit_hdr,
								cfg_noffset);
			fit_uname_kernel = fit_get_name(fit_hdr, os_noffset,
							NULL);
		} else {
			/* get kernel component image node offset */
			bootstage_mark(BOOTSTAGE_ID_FIT_UNIT_NAME);
			os_noffset = fit_image_get_node(fit_hdr,
							fit_uname_kernel);
		}
		if (os_noffset < 0) {
			bootstage_error(BOOTSTAGE_ID_FIT_CONFIG);
			return NULL;
		}

		printf("   Trying '%s' kernel subimage\n", fit_uname_kernel);

		bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_SUBIMAGE);
		if (!fit_check_kernel(fit_hdr, os_noffset, images->verify))
			return NULL;

		/* get kernel image data address and length */
		if (fit_image_get_data(fit_hdr, os_noffset, &data, &len)) {
			puts("Could not find kernel subimage data!\n");
			bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO_ERR);
			return NULL;
		}
		bootstage_mark(BOOTSTAGE_ID_FIT_KERNEL_INFO);

		*os_len = len;
		*os_data = (ulong)data;
		images->fit_hdr_os = (void *)fit_hdr;
		images->fit_uname_os = fit_uname_kernel;
		images->fit_noffset_os = os_noffset;
		break;
#endif
	default:
		printf("Wrong Image Format for %s command\n", cmdtp->name);
		bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
		return NULL;
	}

	debug("   kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
			*os_data, *os_len, *os_len);

	return buf;
}
コード例 #20
0
ファイル: cmd_bootm.c プロジェクト: kontar/u-boot
int do_bootm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	ulong		iflag;
	ulong		load_end = 0;
	int		ret;
	boot_os_fn	*boot_fn;
#ifdef CONFIG_NEEDS_MANUAL_RELOC
	static int relocated = 0;

	if (!relocated) {
		int i;

		/* relocate boot function table */
		for (i = 0; i < ARRAY_SIZE(boot_os); i++)
			if (boot_os[i] != NULL)
				boot_os[i] += gd->reloc_off;

		/* relocate names of sub-command table */
		for (i = 0; i < ARRAY_SIZE(cmd_bootm_sub); i++)
			cmd_bootm_sub[i].name += gd->reloc_off;

		relocated = 1;
	}
#endif

	/* determine if we have a sub command */
	if (argc > 1) {
		char *endp;

		simple_strtoul(argv[1], &endp, 16);
		/* endp pointing to NULL means that argv[1] was just a
		 * valid number, pass it along to the normal bootm processing
		 *
		 * If endp is ':' or '#' assume a FIT identifier so pass
		 * along for normal processing.
		 *
		 * Right now we assume the first arg should never be '-'
		 */
		if ((*endp != 0) && (*endp != ':') && (*endp != '#'))
			return do_bootm_subcommand(cmdtp, flag, argc, argv);
	}

	if (bootm_start(cmdtp, flag, argc, argv))
		return 1;

	/*
	 * 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...
	 */
	iflag = disable_interrupts();

#ifdef CONFIG_NETCONSOLE
	/* Stop the ethernet stack if NetConsole could have left it up */
	eth_halt();
#endif

#if defined(CONFIG_CMD_USB)
	/*
	 * turn off USB to prevent the host controller from writing to the
	 * SDRAM while Linux is booting. This could happen (at least for OHCI
	 * controller), because the HCCA (Host Controller Communication Area)
	 * lies within the SDRAM and the host controller writes continously to
	 * this area (as busmaster!). The HccaFrameNumber is for example
	 * updated every 1 ms within the HCCA structure in SDRAM! For more
	 * details see the OpenHCI specification.
	 */
	usb_stop();
#endif

	ret = bootm_load_os(images.os, &load_end, 1);

	if (ret < 0) {
		if (ret == BOOTM_ERR_RESET)
			do_reset(cmdtp, flag, argc, argv);
		if (ret == BOOTM_ERR_OVERLAP) {
			if (images.legacy_hdr_valid) {
				image_header_t *hdr;
				hdr = &images.legacy_hdr_os_copy;
				if (image_get_type(hdr) == IH_TYPE_MULTI)
					puts("WARNING: legacy format multi "
						"component image "
						"overwritten\n");
			} else {
				puts("ERROR: new format image overwritten - "
					"must RESET the board to recover\n");
				bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
				do_reset(cmdtp, flag, argc, argv);
			}
		}
		if (ret == BOOTM_ERR_UNIMPLEMENTED) {
			if (iflag)
				enable_interrupts();
			bootstage_error(BOOTSTAGE_ID_DECOMP_UNIMPL);
			return 1;
		}
	}

	lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load));

	if (images.os.type == IH_TYPE_STANDALONE) {
		if (iflag)
			enable_interrupts();
		/* This may return when 'autostart' is 'no' */
		bootm_start_standalone(iflag, argc, argv);
		return 0;
	}

	bootstage_mark(BOOTSTAGE_ID_CHECK_BOOT_OS);

#if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY)
	if (images.os.os == IH_OS_LINUX)
		fixup_silent_linux();
#endif

	boot_fn = boot_os[images.os.os];

	if (boot_fn == NULL) {
		if (iflag)
			enable_interrupts();
		printf("ERROR: booting os '%s' (%d) is not supported\n",
			genimg_get_os_name(images.os.os), images.os.os);
		bootstage_error(BOOTSTAGE_ID_CHECK_BOOT_OS);
		return 1;
	}

	arch_preboot_os();

	boot_fn(0, argc, argv, &images);

	bootstage_error(BOOTSTAGE_ID_BOOT_OS_RETURNED);
#ifdef DEBUG
	puts("\n## Control returned to monitor - resetting...\n");
#endif
	do_reset(cmdtp, flag, argc, argv);

	return 1;
}
コード例 #21
0
ファイル: cmd_bootm.c プロジェクト: kontar/u-boot
static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)
{
	uint8_t comp = os.comp;
	ulong load = os.load;
	ulong blob_start = os.start;
	ulong blob_end = os.end;
	ulong image_start = os.image_start;
	ulong image_len = os.image_len;
	__maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN;
	int no_overlap = 0;
#if defined(CONFIG_LZMA) || defined(CONFIG_LZO)
	int ret;
#endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */

	const char *type_name = genimg_get_type_name(os.type);

	switch (comp) {
	case IH_COMP_NONE:
		if (load == blob_start || load == image_start) {
			printf("   XIP %s ... ", type_name);
			no_overlap = 1;
		} else {
			printf("   Loading %s ... ", type_name);
			memmove_wd((void *)load, (void *)image_start,
					image_len, CHUNKSZ);
		}
		*load_end = load + image_len;
		puts("OK\n");
		break;
#ifdef CONFIG_GZIP
	case IH_COMP_GZIP:
		printf("   Uncompressing %s ... ", type_name);
		if (gunzip((void *)load, unc_len,
				(uchar *)image_start, &image_len) != 0) {
			puts("GUNZIP: uncompress, out-of-mem or overwrite "
				"error - must RESET board to recover\n");
			if (boot_progress)
				bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + image_len;
		break;
#endif /* CONFIG_GZIP */
#ifdef CONFIG_BZIP2
	case IH_COMP_BZIP2:
		printf("   Uncompressing %s ... ", type_name);
		/*
		 * If we've got less than 4 MB of malloc() space,
		 * use slower decompression algorithm which requires
		 * at most 2300 KB of memory.
		 */
		int i = BZ2_bzBuffToBuffDecompress((char *)load,
					&unc_len, (char *)image_start, image_len,
					CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
		if (i != BZ_OK) {
			printf("BUNZIP2: uncompress or overwrite error %d "
				"- must RESET board to recover\n", i);
			if (boot_progress)
				bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + unc_len;
		break;
#endif /* CONFIG_BZIP2 */
#ifdef CONFIG_LZMA
	case IH_COMP_LZMA: {
		SizeT lzma_len = unc_len;
		printf("   Uncompressing %s ... ", type_name);

		ret = lzmaBuffToBuffDecompress(
			(unsigned char *)load, &lzma_len,
			(unsigned char *)image_start, image_len);
		unc_len = lzma_len;
		if (ret != SZ_OK) {
			printf("LZMA: uncompress or overwrite error %d "
				"- must RESET board to recover\n", ret);
			bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}
		*load_end = load + unc_len;
		break;
	}
#endif /* CONFIG_LZMA */
#ifdef CONFIG_LZO
	case IH_COMP_LZO:
		printf("   Uncompressing %s ... ", type_name);

		ret = lzop_decompress((const unsigned char *)image_start,
					  image_len, (unsigned char *)load,
					  &unc_len);
		if (ret != LZO_E_OK) {
			printf("LZO: uncompress or overwrite error %d "
			      "- must RESET board to recover\n", ret);
			if (boot_progress)
				bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + unc_len;
		break;
#endif /* CONFIG_LZO */
	default:
		printf("Unimplemented compression type %d\n", comp);
		return BOOTM_ERR_UNIMPLEMENTED;
	}

	flush_cache(load, (*load_end - load) * sizeof(ulong));

	puts("OK\n");
	debug("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
	bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);

	if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) {
		debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
			blob_start, blob_end);
		debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
			*load_end);

		return BOOTM_ERR_OVERLAP;
	}

	return 0;
}
コード例 #22
0
static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
		char * const argv[])
{
	char *s;
	char *end;
	int   rcode = 0;
	int   size;
	ulong addr;

	/* pre-set load_addr */
	if ((s = getenv("loadaddr")) != NULL) {
		load_addr = simple_strtoul(s, NULL, 16);
	}

	switch (argc) {
	case 1:
		break;

	case 2:	/*
		 * Only one arg - accept two forms:
		 * Just load address, or just boot file name. The latter
		 * form must be written in a format which can not be
		 * mis-interpreted as a valid number.
		 */
		addr = simple_strtoul(argv[1], &end, 16);
		if (end == (argv[1] + strlen(argv[1])))
			load_addr = addr;
		else
			copy_filename(BootFile, argv[1], sizeof(BootFile));
		break;

	case 3:	load_addr = simple_strtoul(argv[1], NULL, 16);
		copy_filename(BootFile, argv[2], sizeof(BootFile));

		break;

#ifdef CONFIG_CMD_TFTPPUT
	case 4:
		if (strict_strtoul(argv[1], 16, &save_addr) < 0 ||
			strict_strtoul(argv[2], 16, &save_size) < 0) {
			printf("Invalid address/size\n");
			return cmd_usage(cmdtp);
		}
		copy_filename(BootFile, argv[3], sizeof(BootFile));
		break;
#endif
	default:
		bootstage_error(BOOTSTAGE_ID_NET_START);
		return CMD_RET_USAGE;
	}
	bootstage_mark(BOOTSTAGE_ID_NET_START);

	if ((size = NetLoop(proto)) < 0) {
		bootstage_error(BOOTSTAGE_ID_NET_NETLOOP_OK);
		return 1;
	}
	bootstage_mark(BOOTSTAGE_ID_NET_NETLOOP_OK);

	/* NetLoop ok, update environment */
	netboot_update_env();

	/* done if no file was loaded (no errors though) */
	if (size == 0) {
		bootstage_error(BOOTSTAGE_ID_NET_LOADED);
		return 0;
	}

	/* flush cache */
	flush_cache(load_addr, size);

	bootstage_mark(BOOTSTAGE_ID_NET_LOADED);

	rcode = bootm_maybe_autostart(cmdtp, argv[0]);

	if (rcode < 0)
		bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR);
	else
		bootstage_mark(BOOTSTAGE_ID_NET_DONE);
	return rcode;
}
コード例 #23
0
int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
		    char *const argv[])
{
	int dev, part;
	ulong addr = CONFIG_SYS_LOAD_ADDR;
	ulong cnt;
	disk_partition_t info;
#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
	image_header_t *hdr;
#endif
	block_dev_desc_t *dev_desc;

#if defined(CONFIG_FIT)
	const void *fit_hdr = NULL;
#endif

	bootstage_mark(BOOTSTAGE_ID_IDE_START);
	if (argc > 3) {
		bootstage_error(BOOTSTAGE_ID_IDE_ADDR);
		return CMD_RET_USAGE;
	}
	bootstage_mark(BOOTSTAGE_ID_IDE_ADDR);

	if (argc > 1)
		addr = simple_strtoul(argv[1], NULL, 16);

	bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE);

	part = get_device_and_partition(intf, (argc == 3) ? argv[2] : NULL,
					&dev_desc, &info, 1);
	if (part < 0) {
		bootstage_error(BOOTSTAGE_ID_IDE_TYPE);
		return 1;
	}

	dev = dev_desc->dev;
	bootstage_mark(BOOTSTAGE_ID_IDE_TYPE);

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

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

	if (dev_desc->block_read(dev, info.start, 1, (ulong *) addr) != 1) {
		printf("** Read error on %d:%d\n", dev, part);
		bootstage_error(BOOTSTAGE_ID_IDE_PART_READ);
		return 1;
	}
	bootstage_mark(BOOTSTAGE_ID_IDE_PART_READ);

	switch (genimg_get_format((void *) addr)) {
#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
	case IMAGE_FORMAT_LEGACY:
		hdr = (image_header_t *) addr;

		bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT);

		if (!image_check_hcrc(hdr)) {
			puts("\n** Bad Header Checksum **\n");
			bootstage_error(BOOTSTAGE_ID_IDE_CHECKSUM);
			return 1;
		}
		bootstage_mark(BOOTSTAGE_ID_IDE_CHECKSUM);

		image_print_contents(hdr);

		cnt = image_get_image_size(hdr);
		break;
#endif
#if defined(CONFIG_FIT)
	case IMAGE_FORMAT_FIT:
		fit_hdr = (const void *) addr;
		puts("Fit image detected...\n");

		cnt = fit_get_size(fit_hdr);
		break;
#endif
	default:
		bootstage_error(BOOTSTAGE_ID_IDE_FORMAT);
		puts("** Unknown image type\n");
		return 1;
	}

	cnt += info.blksz - 1;
	cnt /= info.blksz;
	cnt -= 1;

	if (dev_desc->block_read(dev, info.start + 1, cnt,
					 (ulong *)(addr + info.blksz)) != cnt) {
		printf("** Read error on %d:%d\n", dev, part);
		bootstage_error(BOOTSTAGE_ID_IDE_READ);
		return 1;
	}
	bootstage_mark(BOOTSTAGE_ID_IDE_READ);

#if defined(CONFIG_FIT)
	/* This cannot be done earlier,
	 * we need complete FIT image in RAM first */
	if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) {
		if (!fit_check_format(fit_hdr)) {
			bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ);
			puts("** Bad FIT image format\n");
			return 1;
		}
		bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK);
		fit_print_contents(fit_hdr);
	}
#endif

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

	/* Loading ok, update default load address */
	load_addr = addr;

	return bootm_maybe_autostart(cmdtp, argv[0]);
}
コード例 #24
0
ファイル: cmd_bootm.c プロジェクト: kontar/u-boot
static int do_bootm_netbsd(int flag, int argc, char * const argv[],
			    bootm_headers_t *images)
{
	void (*loader)(bd_t *, image_header_t *, char *, char *);
	image_header_t *os_hdr, *hdr;
	ulong kernel_data, kernel_len;
	char *consdev;
	char *cmdline;

	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
		return 1;

#if defined(CONFIG_FIT)
	if (!images->legacy_hdr_valid) {
		fit_unsupported_reset("NetBSD");
		return 1;
	}
#endif
	hdr = images->legacy_hdr_os;

	/*
	 * Booting a (NetBSD) kernel image
	 *
	 * This process is pretty similar to a standalone application:
	 * The (first part of an multi-) image must be a stage-2 loader,
	 * which in turn is responsible for loading & invoking the actual
	 * kernel.  The only differences are the parameters being passed:
	 * besides the board info strucure, the loader expects a command
	 * line, the name of the console device, and (optionally) the
	 * address of the original image header.
	 */
	os_hdr = NULL;
	if (image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {
		image_multi_getimg(hdr, 1, &kernel_data, &kernel_len);
		if (kernel_len)
			os_hdr = hdr;
	}

	consdev = "";
#if   defined(CONFIG_8xx_CONS_SMC1)
	consdev = "smc1";
#elif defined(CONFIG_8xx_CONS_SMC2)
	consdev = "smc2";
#elif defined(CONFIG_8xx_CONS_SCC2)
	consdev = "scc2";
#elif defined(CONFIG_8xx_CONS_SCC3)
	consdev = "scc3";
#endif

	if (argc > 2) {
		ulong len;
		int   i;

		for (i = 2, len = 0; i < argc; i += 1)
			len += strlen(argv[i]) + 1;
		cmdline = malloc(len);

		for (i = 2, len = 0; i < argc; i += 1) {
			if (i > 2)
				cmdline[len++] = ' ';
			strcpy(&cmdline[len], argv[i]);
			len += strlen(argv[i]);
		}
	} else if ((cmdline = getenv("bootargs")) == NULL) {
		cmdline = "";
	}

	loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep;

	printf("## Transferring control to NetBSD stage-2 loader "
		"(at address %08lx) ...\n",
		(ulong)loader);

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

	/*
	 * NetBSD Stage-2 Loader Parameters:
	 *   r3: ptr to board info data
	 *   r4: image address
	 *   r5: console device
	 *   r6: boot args string
	 */
	(*loader)(gd->bd, os_hdr, consdev, cmdline);

	return 1;
}
コード例 #25
0
ファイル: image.c プロジェクト: Android4SAM/u-boot-at91
/**
 * boot_ramdisk_high - relocate init ramdisk
 * @lmb: pointer to lmb handle, will be used for memory mgmt
 * @rd_data: ramdisk data start address
 * @rd_len: ramdisk data length
 * @initrd_start: pointer to a ulong variable, will hold final init ramdisk
 *      start address (after possible relocation)
 * @initrd_end: pointer to a ulong variable, will hold final init ramdisk
 *      end address (after possible relocation)
 *
 * boot_ramdisk_high() takes a relocation hint from "initrd_high" environment
 * variable and if requested ramdisk data is moved to a specified location.
 *
 * Initrd_start and initrd_end are set to final (after relocation) ramdisk
 * start/end addresses if ramdisk image start and len were provided,
 * otherwise set initrd_start and initrd_end set to zeros.
 *
 * returns:
 *      0 - success
 *     -1 - failure
 */
int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
		  ulong *initrd_start, ulong *initrd_end)
{
	char	*s;
	ulong	initrd_high;
	int	initrd_copy_to_ram = 1;

	if ((s = getenv("initrd_high")) != NULL) {
		/* a value of "no" or a similar string will act like 0,
		 * turning the "load high" feature off. This is intentional.
		 */
		initrd_high = simple_strtoul(s, NULL, 16);
		if (initrd_high == ~0)
			initrd_copy_to_ram = 0;
	} else {
		/* not set, no restrictions to load high */
		initrd_high = ~0;
	}


#ifdef CONFIG_LOGBUFFER
	/* Prevent initrd from overwriting logbuffer */
	lmb_reserve(lmb, logbuffer_base() - LOGBUFF_OVERHEAD, LOGBUFF_RESERVE);
#endif

	debug("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
			initrd_high, initrd_copy_to_ram);

	if (rd_data) {
		if (!initrd_copy_to_ram) {	/* zero-copy ramdisk support */
			debug("   in-place initrd\n");
			*initrd_start = rd_data;
			*initrd_end = rd_data + rd_len;
			lmb_reserve(lmb, rd_data, rd_len);
		} else {
			if (initrd_high)
				*initrd_start = (ulong)lmb_alloc_base(lmb,
						rd_len, 0x1000, initrd_high);
			else
				*initrd_start = (ulong)lmb_alloc(lmb, rd_len,
								 0x1000);

			if (*initrd_start == 0) {
				puts("ramdisk - allocation error\n");
				goto error;
			}
			bootstage_mark(BOOTSTAGE_ID_COPY_RAMDISK);

			*initrd_end = *initrd_start + rd_len;
			printf("   Loading Ramdisk to %08lx, end %08lx ... ",
					*initrd_start, *initrd_end);

			memmove_wd((void *)*initrd_start,
					(void *)rd_data, rd_len, CHUNKSZ);

#ifdef CONFIG_MP
			/*
			 * Ensure the image is flushed to memory to handle
			 * AMP boot scenarios in which we might not be
			 * HW cache coherent
			 */
			flush_cache((unsigned long)*initrd_start, rd_len);
#endif
			puts("OK\n");
		}
	} else {
		*initrd_start = 0;
		*initrd_end = 0;
	}
	debug("   ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",
			*initrd_start, *initrd_end);

	return 0;

error:
	return -1;
}
コード例 #26
0
ファイル: image.c プロジェクト: Android4SAM/u-boot-at91
/**
 * boot_get_ramdisk - main ramdisk handling routine
 * @argc: command argument count
 * @argv: command argument list
 * @images: pointer to the bootm images structure
 * @arch: expected ramdisk architecture
 * @rd_start: pointer to a ulong variable, will hold ramdisk start address
 * @rd_end: pointer to a ulong variable, will hold ramdisk end
 *
 * boot_get_ramdisk() is responsible for finding a valid ramdisk image.
 * Curently supported are the following ramdisk sources:
 *      - multicomponent kernel/ramdisk image,
 *      - commandline provided address of decicated ramdisk image.
 *
 * returns:
 *     0, if ramdisk image was found and valid, or skiped
 *     rd_start and rd_end are set to ramdisk start/end addresses if
 *     ramdisk image is found and valid
 *
 *     1, if ramdisk image is found but corrupted, or invalid
 *     rd_start and rd_end are set to 0 if no ramdisk exists
 */
int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,
		uint8_t arch, ulong *rd_start, ulong *rd_end)
{
	ulong rd_addr, rd_load;
	ulong rd_data, rd_len;
#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
	const image_header_t *rd_hdr;
#endif
	void *buf;
#ifdef CONFIG_SUPPORT_RAW_INITRD
	char *end;
#endif
#if defined(CONFIG_FIT)
	const char	*fit_uname_config = images->fit_uname_cfg;
	const char	*fit_uname_ramdisk = NULL;
	ulong		default_addr;
	int		rd_noffset;
#endif
	const char *select = NULL;

	*rd_start = 0;
	*rd_end = 0;

	if (argc >= 2)
		select = argv[1];
	/*
	 * Look for a '-' which indicates to ignore the
	 * ramdisk argument
	 */
	if (select && strcmp(select, "-") ==  0) {
		debug("## Skipping init Ramdisk\n");
		rd_len = rd_data = 0;
	} else if (select || genimg_has_config(images)) {
#if defined(CONFIG_FIT)
		if (select) {
			/*
			 * If the init ramdisk comes from the FIT image and
			 * the FIT image address is omitted in the command
			 * line argument, try to use os FIT image address or
			 * default load address.
			 */
			if (images->fit_uname_os)
				default_addr = (ulong)images->fit_hdr_os;
			else
				default_addr = load_addr;

			if (fit_parse_conf(select, default_addr,
					   &rd_addr, &fit_uname_config)) {
				debug("*  ramdisk: config '%s' from image at "
						"0x%08lx\n",
						fit_uname_config, rd_addr);
			} else if (fit_parse_subimage(select, default_addr,
						&rd_addr, &fit_uname_ramdisk)) {
				debug("*  ramdisk: subimage '%s' from image at "
						"0x%08lx\n",
						fit_uname_ramdisk, rd_addr);
			} else
#endif
			{
				rd_addr = simple_strtoul(select, NULL, 16);
				debug("*  ramdisk: cmdline image address = "
						"0x%08lx\n",
						rd_addr);
			}
#if defined(CONFIG_FIT)
		} else {
			/* use FIT configuration provided in first bootm
			 * command argument. If the property is not defined,
			 * quit silently.
			 */
			rd_addr = map_to_sysmem(images->fit_hdr_os);
			rd_noffset = fit_get_node_from_config(images,
					FIT_RAMDISK_PROP, rd_addr);
			if (rd_noffset == -ENOLINK)
				return 0;
			else if (rd_noffset < 0)
				return 1;
		}
#endif

		/* copy from dataflash if needed */
		rd_addr = genimg_get_image(rd_addr);

		/*
		 * Check if there is an initrd image at the
		 * address provided in the second bootm argument
		 * check image type, for FIT images get FIT node.
		 */
		buf = map_sysmem(rd_addr, 0);
		switch (genimg_get_format(buf)) {
#if defined(CONFIG_IMAGE_FORMAT_LEGACY)
		case IMAGE_FORMAT_LEGACY:
			printf("## Loading init Ramdisk from Legacy "
					"Image at %08lx ...\n", rd_addr);

			bootstage_mark(BOOTSTAGE_ID_CHECK_RAMDISK);
			rd_hdr = image_get_ramdisk(rd_addr, arch,
							images->verify);

			if (rd_hdr == NULL)
				return 1;

			rd_data = image_get_data(rd_hdr);
			rd_len = image_get_data_size(rd_hdr);
			rd_load = image_get_load(rd_hdr);
			break;
#endif
#if defined(CONFIG_FIT)
		case IMAGE_FORMAT_FIT:
			rd_noffset = fit_image_load(images,
					rd_addr, &fit_uname_ramdisk,
					&fit_uname_config, arch,
					IH_TYPE_RAMDISK,
					BOOTSTAGE_ID_FIT_RD_START,
					FIT_LOAD_IGNORED, &rd_data, &rd_len);
			if (rd_noffset < 0)
				return 1;

			images->fit_hdr_rd = map_sysmem(rd_addr, 0);
			images->fit_uname_rd = fit_uname_ramdisk;
			images->fit_noffset_rd = rd_noffset;
			break;
#endif
		default:
#ifdef CONFIG_SUPPORT_RAW_INITRD
			end = NULL;
			if (select)
				end = strchr(select, ':');
			if (end) {
				rd_len = simple_strtoul(++end, NULL, 16);
				rd_data = rd_addr;
			} else
#endif
			{
				puts("Wrong Ramdisk Image Format\n");
				rd_data = rd_len = rd_load = 0;
				return 1;
			}
		}
	} else if (images->legacy_hdr_valid &&
			image_check_type(&images->legacy_hdr_os_copy,
						IH_TYPE_MULTI)) {

		/*
		 * Now check if we have a legacy mult-component image,
		 * get second entry data start address and len.
		 */
		bootstage_mark(BOOTSTAGE_ID_RAMDISK);
		printf("## Loading init Ramdisk from multi component "
				"Legacy Image at %08lx ...\n",
				(ulong)images->legacy_hdr_os);

		image_multi_getimg(images->legacy_hdr_os, 1, &rd_data, &rd_len);
	}
#ifdef CONFIG_ANDROID_BOOT_IMAGE
	else if ((genimg_get_format(images) == IMAGE_FORMAT_ANDROID) &&
		 (!android_image_get_ramdisk((void *)images->os.start,
		 &rd_data, &rd_len))) {
		/* empty */
	}
#endif
	else {
		/*
		 * no initrd image
		 */
		bootstage_mark(BOOTSTAGE_ID_NO_RAMDISK);
		rd_len = rd_data = 0;
	}

	if (!rd_data) {
		debug("## No init Ramdisk\n");
	} else {
		*rd_start = rd_data;
		*rd_end = rd_data + rd_len;
	}
	debug("   ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",
			*rd_start, *rd_end);

	return 0;
}
コード例 #27
0
ファイル: bootm.c プロジェクト: 01hyang/u-boot
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
{
	bd_t	*bd = gd->bd;
	char	*s;
	int	machid = bd->bi_arch_number;
	void	(*theKernel)(int zero, int arch, uint params);

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

	/*
	 * allow the PREP bootm subcommand, it is required for bootm to work
	 */
	if (flag & BOOTM_STATE_OS_PREP)
		return 0;

	if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
		return 1;

	theKernel = (void (*)(int, int, uint))images->ep;

	s = getenv("machid");
	if (s) {
		machid = simple_strtoul(s, NULL, 16);
		printf("Using machid 0x%x from environment\n", machid);
	}

	bootstage_mark(BOOTSTAGE_ID_RUN_OS);

	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)
	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 (images->rd_start && images->rd_end)
		setup_initrd_tag(bd, images->rd_start, images->rd_end);
#endif
	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, machid, bd->bi_boot_params);
	/* does not return */

	return 1;
}
コード例 #28
0
ファイル: cmd_bootm.c プロジェクト: BuloZB/u-boot-imx
static int bootm_load_os(bootm_headers_t *images, unsigned long *load_end,
		int boot_progress)
{
	image_info_t os = images->os;
	uint8_t comp = os.comp;
	ulong load = os.load;
	ulong blob_start = os.start;
	ulong blob_end = os.end;
	ulong image_start = os.image_start;
	ulong image_len = os.image_len;
	__maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN;
	int no_overlap = 0;
	void *load_buf, *image_buf;
#if defined(CONFIG_LZMA) || defined(CONFIG_LZO)
	int ret;
#endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */

	const char *type_name = genimg_get_type_name(os.type);

	load_buf = map_sysmem(load, unc_len);
	image_buf = map_sysmem(image_start, image_len);
	switch (comp) {
	case IH_COMP_NONE:
		if (load == image_start) {
			printf("   XIP %s ... ", type_name);
			no_overlap = 1;
		} else {
			printf("   Loading %s ... ", type_name);
			memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);
		}
		*load_end = load + image_len;
		break;
#ifdef CONFIG_GZIP
	case IH_COMP_GZIP:
		printf("   Uncompressing %s ... ", type_name);
		if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) {
			puts("GUNZIP: uncompress, out-of-mem or overwrite "
				"error - must RESET board to recover\n");
			if (boot_progress)
				bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + image_len;
		break;
#endif /* CONFIG_GZIP */
#ifdef CONFIG_BZIP2
	case IH_COMP_BZIP2:
		printf("   Uncompressing %s ... ", type_name);
		/*
		 * If we've got less than 4 MB of malloc() space,
		 * use slower decompression algorithm which requires
		 * at most 2300 KB of memory.
		 */
		int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len,
			image_buf, image_len,
			CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
		if (i != BZ_OK) {
			printf("BUNZIP2: uncompress or overwrite error %d "
				"- must RESET board to recover\n", i);
			if (boot_progress)
				bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + unc_len;
		break;
#endif /* CONFIG_BZIP2 */
#ifdef CONFIG_LZMA
	case IH_COMP_LZMA: {
		SizeT lzma_len = unc_len;
		printf("   Uncompressing %s ... ", type_name);

		ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len,
					       image_buf, image_len);
		unc_len = lzma_len;
		if (ret != SZ_OK) {
			printf("LZMA: uncompress or overwrite error %d "
				"- must RESET board to recover\n", ret);
			bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}
		*load_end = load + unc_len;
		break;
	}
#endif /* CONFIG_LZMA */
#ifdef CONFIG_LZO
	case IH_COMP_LZO: {
		size_t size = unc_len;

		printf("   Uncompressing %s ... ", type_name);

		ret = lzop_decompress(image_buf, image_len, load_buf, &size);
		if (ret != LZO_E_OK) {
			printf("LZO: uncompress or overwrite error %d "
			      "- must RESET board to recover\n", ret);
			if (boot_progress)
				bootstage_error(BOOTSTAGE_ID_DECOMP_IMAGE);
			return BOOTM_ERR_RESET;
		}

		*load_end = load + size;
		break;
	}
#endif /* CONFIG_LZO */
	default:
		printf("Unimplemented compression type %d\n", comp);
		return BOOTM_ERR_UNIMPLEMENTED;
	}

	flush_cache(load, (*load_end - load) * sizeof(ulong));

	puts("OK\n");
	debug("   kernel loaded at 0x%08lx, end = 0x%08lx\n", load, *load_end);
	bootstage_mark(BOOTSTAGE_ID_KERNEL_LOADED);

	if (!no_overlap && (load < blob_end) && (*load_end > blob_start)) {
		debug("images.os.start = 0x%lX, images.os.end = 0x%lx\n",
			blob_start, blob_end);
		debug("images.os.load = 0x%lx, load_end = 0x%lx\n", load,
			*load_end);

		/* Check what type of image this is. */
		if (images->legacy_hdr_valid) {
			if (image_get_type(&images->legacy_hdr_os_copy)
					== IH_TYPE_MULTI)
				puts("WARNING: legacy format multi component image overwritten\n");
			return BOOTM_ERR_OVERLAP;
		} else {
			puts("ERROR: new format image overwritten - must RESET the board to recover\n");
			bootstage_error(BOOTSTAGE_ID_OVERWRITTEN);
			return BOOTM_ERR_RESET;
		}
	}

	return 0;
}
コード例 #29
0
ファイル: image-fit.c プロジェクト: bbbLinux/u_boot
int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr,
		   const char **fit_unamep, const char **fit_uname_configp,
		   int arch, int image_type, int bootstage_id,
		   enum fit_load_op load_op, ulong *datap, ulong *lenp)
{
	int cfg_noffset, noffset;
	const char *fit_uname;
	const char *fit_uname_config;
	const void *fit;
	const void *buf;
	size_t size;
	int type_ok, os_ok;
	ulong load, data, len;
	int ret;

	fit = map_sysmem(addr, 0);
	fit_uname = fit_unamep ? *fit_unamep : NULL;
	fit_uname_config = fit_uname_configp ? *fit_uname_configp : NULL;
	printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr);

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT);
	if (!fit_check_format(fit)) {
		printf("Bad FIT %s image format!\n", prop_name);
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT);
		return -ENOEXEC;
	}
	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK);
	if (fit_uname) {
		/* get ramdisk component image node offset */
		bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME);
		noffset = fit_image_get_node(fit, fit_uname);
	} else {
		/*
		 * no image node unit name, try to get config
		 * node first. If config unit node name is NULL
		 * fit_conf_get_node() will try to find default config node
		 */
		bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME);
		if (IMAGE_ENABLE_BEST_MATCH && !fit_uname_config) {
			cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob());
		} else {
			cfg_noffset = fit_conf_get_node(fit,
							fit_uname_config);
		}
		if (cfg_noffset < 0) {
			puts("Could not find configuration node\n");
			bootstage_error(bootstage_id +
					BOOTSTAGE_SUB_NO_UNIT_NAME);
			return -ENOENT;
		}
		fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL);
		printf("   Using '%s' configuration\n", fit_uname_config);
		if (image_type == IH_TYPE_KERNEL) {
			/* Remember (and possibly verify) this config */
			images->fit_uname_cfg = fit_uname_config;
			if (IMAGE_ENABLE_VERIFY && images->verify) {
				puts("   Verifying Hash Integrity ... ");
				if (!fit_config_verify(fit, cfg_noffset)) {
					puts("Bad Data Hash\n");
					bootstage_error(bootstage_id +
						BOOTSTAGE_SUB_HASH);
					return -EACCES;
				}
				puts("OK\n");
			}
			bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG);
		}

		noffset = fit_conf_get_prop_node(fit, cfg_noffset,
						 prop_name);
		fit_uname = fit_get_name(fit, noffset, NULL);
	}
	if (noffset < 0) {
		puts("Could not find subimage node\n");
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE);
		return -ENOENT;
	}

	printf("   Trying '%s' %s subimage\n", fit_uname, prop_name);

	ret = fit_image_select(fit, noffset, images->verify);
	if (ret) {
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH);
		return ret;
	}

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
	if (!fit_image_check_target_arch(fit, noffset)) {
		puts("Unsupported Architecture\n");
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH);
		return -ENOEXEC;
	}

	if (image_type == IH_TYPE_FLATDT &&
	    !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) {
		puts("FDT image is compressed");
		return -EPROTONOSUPPORT;
	}

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
	type_ok = fit_image_check_type(fit, noffset, image_type) ||
		(image_type == IH_TYPE_KERNEL &&
			fit_image_check_type(fit, noffset,
					     IH_TYPE_KERNEL_NOLOAD));
	os_ok = image_type == IH_TYPE_FLATDT ||
		fit_image_check_os(fit, noffset, IH_OS_LINUX);
	if (!type_ok || !os_ok) {
		printf("No Linux %s %s Image\n", genimg_get_arch_name(arch),
		       genimg_get_type_name(image_type));
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL);
		return -EIO;
	}

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK);

	/* get image data address and length */
	if (fit_image_get_data(fit, noffset, &buf, &size)) {
		printf("Could not find %s subimage data!\n", prop_name);
		bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA);
		return -ENOENT;
	}
	len = (ulong)size;

	/* verify that image data is a proper FDT blob */
	if (image_type == IH_TYPE_FLATDT && fdt_check_header((char *)buf)) {
		puts("Subimage data is not a FDT");
		return -ENOEXEC;
	}

	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK);

	/*
	 * Work-around for eldk-4.2 which gives this warning if we try to
	 * case in the unmap_sysmem() call:
	 * warning: initialization discards qualifiers from pointer target type
	 */
	{
		void *vbuf = (void *)buf;

		data = map_to_sysmem(vbuf);
	}

	if (load_op == FIT_LOAD_IGNORED) {
		/* Don't load */
	} else if (fit_image_get_load(fit, noffset, &load)) {
		if (load_op == FIT_LOAD_REQUIRED) {
			printf("Can't get %s subimage load address!\n",
			       prop_name);
			bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD);
			return -EBADF;
		}
	} else {
		ulong image_start, image_end;
		ulong load_end;
		void *dst;

		/*
		 * move image data to the load address,
		 * make sure we don't overwrite initial image
		 */
		image_start = addr;
		image_end = addr + fit_get_size(fit);

		load_end = load + len;
		if (image_type != IH_TYPE_KERNEL &&
		    load < image_end && load_end > image_start) {
			printf("Error: %s overwritten\n", prop_name);
			return -EXDEV;
		}

		printf("   Loading %s from 0x%08lx to 0x%08lx\n",
		       prop_name, data, load);

		dst = map_sysmem(load, len);
		memmove(dst, buf, len);
		data = load;
	}
	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD);

	*datap = data;
	*lenp = len;
	if (fit_unamep)
		*fit_unamep = (char *)fit_uname;
	if (fit_uname_configp)
		*fit_uname_configp = (char *)fit_uname_config;

	return noffset;
}
コード例 #30
0
ファイル: cmd_bootm.c プロジェクト: BuloZB/u-boot-imx
/**
 * boot_get_kernel - find kernel image
 * @os_data: pointer to a ulong variable, will hold os data start address
 * @os_len: pointer to a ulong variable, will hold os data length
 *
 * boot_get_kernel() tries to find a kernel image, verifies its integrity
 * and locates kernel data.
 *
 * returns:
 *     pointer to image header if valid image was found, plus kernel start
 *     address and length, otherwise NULL
 */
static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
		char * const argv[], bootm_headers_t *images, ulong *os_data,
		ulong *os_len)
{
	image_header_t	*hdr;
	ulong		img_addr;
	const void *buf;
#if defined(CONFIG_FIT)
	const char	*fit_uname_config = NULL;
	const char	*fit_uname_kernel = NULL;
	int		os_noffset;
#endif

	/* find out kernel image address */
	if (argc < 1) {
		img_addr = load_addr;
		debug("*  kernel: default image load address = 0x%08lx\n",
				load_addr);
#if defined(CONFIG_FIT)
	} else if (fit_parse_conf(argv[0], load_addr, &img_addr,
							&fit_uname_config)) {
		debug("*  kernel: config '%s' from image at 0x%08lx\n",
				fit_uname_config, img_addr);
	} else if (fit_parse_subimage(argv[0], load_addr, &img_addr,
							&fit_uname_kernel)) {
		debug("*  kernel: subimage '%s' from image at 0x%08lx\n",
				fit_uname_kernel, img_addr);
#endif
	} else {
		img_addr = simple_strtoul(argv[0], NULL, 16);
		debug("*  kernel: cmdline image address = 0x%08lx\n", img_addr);
	}

	bootstage_mark(BOOTSTAGE_ID_CHECK_MAGIC);

	/* copy from dataflash if needed */
	img_addr = genimg_get_image(img_addr);

	/* check image type, for FIT images get FIT kernel node */
	*os_data = *os_len = 0;
	buf = map_sysmem(img_addr, 0);
	switch (genimg_get_format(buf)) {
	case IMAGE_FORMAT_LEGACY:
		printf("## Booting kernel from Legacy Image at %08lx ...\n",
				img_addr);
		hdr = image_get_kernel(img_addr, images->verify);
		if (!hdr)
			return NULL;
		bootstage_mark(BOOTSTAGE_ID_CHECK_IMAGETYPE);

		/* get os_data and os_len */
		switch (image_get_type(hdr)) {
		case IH_TYPE_KERNEL:
		case IH_TYPE_KERNEL_NOLOAD:
			*os_data = image_get_data(hdr);
			*os_len = image_get_data_size(hdr);
			break;
		case IH_TYPE_MULTI:
			image_multi_getimg(hdr, 0, os_data, os_len);
			break;
		case IH_TYPE_STANDALONE:
			*os_data = image_get_data(hdr);
			*os_len = image_get_data_size(hdr);
			break;
		default:
			printf("Wrong Image Type for %s command\n",
				cmdtp->name);
			bootstage_error(BOOTSTAGE_ID_CHECK_IMAGETYPE);
			return NULL;
		}

		/*
		 * copy image header to allow for image overwrites during
		 * kernel decompression.
		 */
		memmove(&images->legacy_hdr_os_copy, hdr,
			sizeof(image_header_t));

		/* save pointer to image header */
		images->legacy_hdr_os = hdr;

		images->legacy_hdr_valid = 1;
		bootstage_mark(BOOTSTAGE_ID_DECOMP_IMAGE);
		break;
#if defined(CONFIG_FIT)
	case IMAGE_FORMAT_FIT:
		os_noffset = fit_image_load(images, FIT_KERNEL_PROP,
				img_addr,
				&fit_uname_kernel, &fit_uname_config,
				IH_ARCH_DEFAULT, IH_TYPE_KERNEL,
				BOOTSTAGE_ID_FIT_KERNEL_START,
				FIT_LOAD_IGNORED, os_data, os_len);
		if (os_noffset < 0)
			return NULL;

		images->fit_hdr_os = map_sysmem(img_addr, 0);
		images->fit_uname_os = fit_uname_kernel;
		images->fit_uname_cfg = fit_uname_config;
		images->fit_noffset_os = os_noffset;
		break;
#endif
#ifdef CONFIG_ANDROID_BOOT_IMAGE
	case IMAGE_FORMAT_ANDROID:
		printf("## Booting Android Image at 0x%08lx ...\n", img_addr);
		if (android_image_get_kernel((void *)img_addr, images->verify,
					     os_data, os_len))
			return NULL;
		break;
#endif
	default:
		printf("Wrong Image Format for %s command\n", cmdtp->name);
		bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO);
		return NULL;
	}

	debug("   kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",
			*os_data, *os_len, *os_len);

	return buf;
}