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; }
/* 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 }