예제 #1
0
파일: booti.c 프로젝트: liyaoshi/omapboot
int do_booti(struct bootloader_ops *boot_ops, char *info, void *download_addr)
{
	boot_img_hdr *hdr;
	u32 addr;
	u64 sector1, sector2;
	char *ptn = "boot";
	int boot_from_mmc = 0;
	u64 num_sectors = 0;
	int sector_sz = 0;
	int ret = 0;
	unsigned dbt_addr = CONFIG_ADDR_ATAGS;
	unsigned cfg_machine_type = CONFIG_BOARD_MACH_TYPE;
	void (*theKernel)(int zero, int arch, void *);

	if (!(strcmp(info, "storage")))
		boot_from_mmc = 1;

	if (download_addr != NULL)
		addr = (u32) download_addr;
	else
		addr = CONFIG_ADDR_DOWNLOAD;

	hdr = (boot_img_hdr *) addr;

	if (boot_from_mmc) {

		struct fastboot_ptentry *pte;

		ret = load_ptbl(boot_ops->storage_ops, 0);
		if (ret != 0)
			goto fail;

		dbt_addr = load_dev_tree(boot_ops, dbt_addr);
		if (dbt_addr < 0)
			goto fail;

		pte = fastboot_flash_find_ptn(ptn);
		if (!pte) {
			printf("booti: cannot find '%s' partition\n", ptn);
			goto fail;
		}

		sector_sz = boot_ops->storage_ops->get_sector_size();
		num_sectors =  sizeof(boot_img_hdr) / sector_sz;
		ret = boot_ops->storage_ops->read(pte->start, num_sectors,
							(void *) hdr);
		if (ret != 0) {
			printf("booti: failed to read bootimg header\n");
			goto fail;
		} else
			bootimg_print_image_hdr(hdr);

		ret = memcmp(hdr->magic, BOOT_MAGIC, 8);
		if (ret != 0) {
			printf("booti: bad boot image magic\n");
			goto fail;
		}

		sector1 = pte->start + (hdr->page_size / sector_sz);

		sector2 = sector1 +
			ALIGN(hdr->kernel_size, hdr->page_size) / sector_sz;

		num_sectors = CEIL(hdr->kernel_size, sector_sz);
		if (num_sectors <= (hdr->kernel_size / sector_sz))
			num_sectors = (hdr->kernel_size / sector_sz);

		DBG("Reading kernel from start sector %d and reading %d "
			"number of sectors\n", (int)sector1, (int)num_sectors);

		ret = boot_ops->storage_ops->read(sector1, num_sectors,
					(void *) hdr->kernel_addr);
		if (ret != 0) {
			printf("mmc read failed\n");
			goto fail;
		}

		DBG("Done reading kernel from mmc\n");

		num_sectors = CEIL(hdr->ramdisk_size, sector_sz);
		if (num_sectors <= (hdr->ramdisk_size / sector_sz))
			num_sectors = (hdr->ramdisk_size / sector_sz);

		DBG("Reading ramdisk from start sector %d and reading %d "
			"number of sectors\n", (int)sector2, (int)num_sectors);

		ret = boot_ops->storage_ops->read(sector2, num_sectors,
					(void *) hdr->ramdisk_addr);
		if (ret != 0) {
			printf("mmc read failed\n");
			goto fail;
		}

		DBG("Done reading ramdisk from mmc\n");

	} else {
		u32 kaddr, raddr;

		DBG("user wants to boot an image downloaded using "
							"fastboot\n");

		ret = memcmp(hdr->magic, BOOT_MAGIC, 8);
		if (ret != 0) {
			printf("booti: bad boot image magic\n");
			goto fail;
		}

		bootimg_print_image_hdr(hdr);

		kaddr = addr + hdr->page_size;

		raddr = kaddr + ALIGN(hdr->kernel_size, hdr->page_size);

		memmove((void *) hdr->kernel_addr, (void *)kaddr,
							hdr->kernel_size);
		memmove((void *) hdr->ramdisk_addr, (void *)raddr,
							hdr->ramdisk_size);
	}

	printf("kernel   @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size);
	printf("ramdisk  @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size);

#if defined CONFIG_OMAP4_ANDROID_CMD_LINE || \
	defined CONFIG_OMAP5_ANDROID_CMD_LINE
	boot_settings(boot_ops, &hdr[0], CONFIG_ADDR_ATAGS);
#endif

#if defined START_HYPERVISOR_MODE && defined CONFIG_IS_OMAP5
	if (!(strcmp(boot_ops->proc_ops->proc_get_type(), "GP"))) {
		printf("Starting ARM Hyp mode\n");
		start_hyp_mode(MONITOR_API_START_HYPERVISOR);
	}
#endif

	theKernel = (void (*)(int, int, void *))(hdr->kernel_addr);

	printf("booting kernel...\n");
	theKernel(0, cfg_machine_type, (void *)dbt_addr);

fail:
	ret = boot_ops->usb_ops->usb_open(boot_ops->usb_ops->usb, INIT_USB,
							boot_ops->proc_ops);
	if (ret != 0) {
		printf("\nusb_open failed\n");
		return ret;
	}
	do_fastboot(boot_ops);
	return 0;
}
예제 #2
0
/* booti <addr> [ mmc0 | mmc1 [ <partition> ] ] */
int do_booti(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	unsigned addr = 0;
	char *ptn = "boot";
	int mmcc = -1;
	boot_img_hdr *hdr = (void *)boothdr;
#ifdef CONFIG_SECURE_BOOT
    u_int32_t load_addr;
    uint32_t image_size;
#endif

	if (argc < 2)
		return -1;

	if (!strncmp(argv[1], "mmc", 3))
		mmcc = simple_strtoul(argv[1]+3, NULL, 10);
	else
		addr = simple_strtoul(argv[1], NULL, 16);

	if (argc > 2)
		ptn = argv[2];

	if (mmcc != -1) {
#ifdef CONFIG_MMC
		struct fastboot_ptentry *pte;
		struct mmc *mmc;
		disk_partition_t info;
		block_dev_desc_t *dev_desc = NULL;
		unsigned sector, partno = -1;

		memset((void *)&info, 0 , sizeof(disk_partition_t));
		/* i.MX use MBR as partition table, so this will have
		   to find the start block and length for the
		   partition name and register the fastboot pte we
		   define the partition number of each partition in
		   config file
		 */
		mmc = find_mmc_device(mmcc);
		if (!mmc) {
			printf("booti: cannot find '%d' mmc device\n", mmcc);
			goto fail;
		}
		dev_desc = get_dev("mmc", mmcc);
		if (NULL == dev_desc) {
			printf("** Block device MMC %d not supported\n", mmcc);
			goto fail;
		}

		/* below was i.MX mmc operation code */
		if (mmc_init(mmc)) {
			printf("mmc%d init failed\n", mmcc);
			goto fail;
		}

#ifdef CONFIG_ANDROID_BOOT_PARTITION_MMC
#ifdef CONFIG_ANDROID_RECOVERY_PARTITION_MMC
		if (!strcmp(ptn, "boot"))
			partno = CONFIG_ANDROID_BOOT_PARTITION_MMC;
		if (!strcmp(ptn, "recovery"))
			partno = CONFIG_ANDROID_RECOVERY_PARTITION_MMC;

		if (get_partition_info(dev_desc, partno, &info)) {
			printf("booti: device don't have such partition:%s\n", ptn);
			goto fail;
		}
#endif
#endif

#ifdef CONFIG_FASTBOOT
		fastboot_ptentry the_partition = {
			.start = info.start,
			.length = info.start * info.blksz,
			.flags = 0,
			.partition_id = 0,
		};
		strncpy(the_partition.name, ptn, 10);
		fastboot_flash_add_ptn(&the_partition);
		/* fastboot_flash_dump_ptn(); */

		pte = fastboot_flash_find_ptn(ptn);
		if (!pte) {
			printf("booti: cannot find '%s' partition\n", ptn);
			goto fail;
		}

		if (mmc->block_dev.block_read(mmcc, pte->start,
					      1, (void *)hdr) < 0) {
			printf("booti: mmc failed to read bootimg header\n");
			goto fail;
		}
			/* flush cache after read */
		flush_cache((ulong)hdr, 512); /* FIXME */

		if (memcmp(hdr->magic, BOOT_MAGIC, 8)) {
			printf("booti: bad boot image magic\n");
			goto fail;
		}

		sector = pte->start + (hdr->page_size / 512);
#else
		if (mmc->block_dev.block_read(mmcc, info.start,
					      1, (void *)hdr) < 0) {
			printf("booti: mmc failed to read bootimg header\n");
			goto fail;
		}
			/* flush cache after read */
		flush_cache((ulong)hdr, 512); /* FIXME */

		if (memcmp(hdr->magic, BOOT_MAGIC, 8)) {
			printf("booti: bad boot image magic\n");
			goto fail;
		}

		sector = info.start + (hdr->page_size / 512);
#endif
		if (mmc->block_dev.block_read(mmcc, sector,
					      (hdr->kernel_size / 512) + 1,
					      (void *)hdr->kernel_addr) < 0) {
			printf("booti: mmc failed to read kernel\n");
			goto fail;
		}
		/* flush cache after read */
		flush_cache((ulong)hdr->kernel_addr, hdr->kernel_size); /* FIXME */
		sector += ALIGN_SECTOR(hdr->kernel_size, hdr->page_size) / 512;
		if (mmc->block_dev.block_read(mmcc, sector,
					      (hdr->ramdisk_size / 512) + 1,
					      (void *)hdr->ramdisk_addr) < 0) {
			printf("booti: mmc failed to read kernel\n");
			goto fail;
		}
		/* flush cache after read */
		flush_cache((ulong)hdr->ramdisk_addr, hdr->ramdisk_size); /* FIXME */
#else
		return -1;
#endif
	} else {
		unsigned kaddr, raddr;

		/* set this aside somewhere safe */
		memcpy(hdr, (void *) addr, sizeof(*hdr));

		if (memcmp(hdr->magic, BOOT_MAGIC, 8)) {
			printf("booti: bad boot image magic\n");
			return 1;
		}

		bootimg_print_image_hdr(hdr);

		kaddr = addr + hdr->page_size;
		raddr = kaddr + ALIGN_SECTOR(hdr->kernel_size, hdr->page_size);

		memmove((void *) hdr->kernel_addr, (void *)kaddr, hdr->kernel_size);
		memmove((void *) hdr->ramdisk_addr, (void *)raddr, hdr->ramdisk_size);
	}

	printf("kernel   @ %08x (%d)\n", hdr->kernel_addr, hdr->kernel_size);
	printf("ramdisk  @ %08x (%d)\n", hdr->ramdisk_addr, hdr->ramdisk_size);

#ifdef CONFIG_SECURE_BOOT
#define IVT_SIZE 0x20
#define CSF_PAD_SIZE 0x2000
	extern uint32_t authenticate_image(uint32_t ddr_start,
					   uint32_t image_size);

	image_size = hdr->ramdisk_addr + hdr->ramdisk_size - hdr->kernel_addr -
		IVT_SIZE - CSF_PAD_SIZE;

	if (authenticate_image(hdr->kernel_addr, image_size))
		printf("Authentication Successful\n");
	else
		printf("Authentication Failed\n");
#endif

	do_booti_linux(hdr);

	puts ("booti: Control returned to monitor - resetting...\n");
	do_reset (cmdtp, flag, argc, argv);
	return 1;

fail:
#ifdef CONFIG_FASTBOOT
	return do_fastboot(NULL, 0, 0, NULL);
#else
	return -1;
#endif
}