void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); if (image_get_magic(header) == IH_MAGIC) { if (spl_image.flags & SPL_COPY_PAYLOAD_ONLY) { /* * On some system (e.g. powerpc), the load-address and * entry-point is located at address 0. We can't load * to 0-0x40. So skip header in this case. */ spl_image.load_addr = image_get_load(header); spl_image.entry_point = image_get_ep(header); spl_image.size = image_get_data_size(header); } else { spl_image.entry_point = image_get_load(header); /* Load including the header */ spl_image.load_addr = spl_image.entry_point - header_size; spl_image.size = image_get_data_size(header) + header_size; } spl_image.os = image_get_os(header); spl_image.name = image_get_name(header); debug("spl: payload image: %.*s load addr: 0x%x size: %d\n", (int)sizeof(spl_image.name), spl_image.name, spl_image.load_addr, spl_image.size); } else { /* Signature not found - assume u-boot.bin */ debug("mkimage signature not found - ih_magic = %x\n", header->ih_magic); spl_set_header_raw_uboot(); } }
static int spl_nor_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { int ret; /* * Loading of the payload to SDRAM is done with skipping of * the mkimage header in this SPL NOR driver */ spl_image->flags |= SPL_COPY_PAYLOAD_ONLY; #ifdef CONFIG_SPL_OS_BOOT if (!spl_start_uboot()) { const struct image_header *header; /* * Load Linux from its location in NOR flash to its defined * location in SDRAM */ header = (const struct image_header *)CONFIG_SYS_OS_BASE; if (image_get_os(header) == IH_OS_LINUX) { /* happy - was a Linux */ ret = spl_parse_image_header(spl_image, header); if (ret) return ret; memcpy((void *)spl_image->load_addr, (void *)(CONFIG_SYS_OS_BASE + sizeof(struct image_header)), spl_image->size); spl_image->arg = (void *)CONFIG_SYS_FDT_BASE; return 0; } else { puts("The Expected Linux image was not found.\n" "Please check your NOR configuration.\n" "Trying to start u-boot now...\n"); } } #endif /* * Load real U-Boot from its location in NOR flash to its * defined location in SDRAM */ ret = spl_parse_image_header(spl_image, (const struct image_header *)CONFIG_SYS_UBOOT_BASE); if (ret) return ret; memcpy((void *)(unsigned long)spl_image->load_addr, (void *)(CONFIG_SYS_UBOOT_BASE + sizeof(struct image_header)), spl_image->size); return 0; }
void spl_nor_load_image(void) { /* * Loading of the payload to SDRAM is done with skipping of * the mkimage header in this SPL NOR driver */ spl_image.flags |= SPL_COPY_PAYLOAD_ONLY; #ifdef CONFIG_SPL_OS_BOOT if (!spl_start_uboot()) { const struct image_header *header; /* * Load Linux from its location in NOR flash to its defined * location in SDRAM */ header = (const struct image_header *)CONFIG_SYS_OS_BASE; if (image_get_os(header) == IH_OS_LINUX) { /* happy - was a Linux */ spl_parse_image_header(header); memcpy((void *)spl_image.load_addr, (void *)(CONFIG_SYS_OS_BASE + sizeof(struct image_header)), spl_image.size); /* * Copy DT blob (fdt) to SDRAM. Passing pointer to * flash doesn't work (16 KiB should be enough for DT) */ memcpy((void *)CONFIG_SYS_SPL_ARGS_ADDR, (void *)(CONFIG_SYS_FDT_BASE), (16 << 10)); return; } else { puts("The Expected Linux image was not found.\n" "Please check your NOR configuration.\n" "Trying to start u-boot now...\n"); } } #endif /* * Load real U-Boot from its location in NOR flash to its * defined location in SDRAM */ spl_parse_image_header( (const struct image_header *)CONFIG_SYS_UBOOT_BASE); memcpy((void *)spl_image.load_addr, (void *)(CONFIG_SYS_UBOOT_BASE + sizeof(struct image_header)), spl_image.size); }
static void image_print_type(const image_header_t *hdr) { const char *os, *arch, *type, *comp; os = image_get_os_name(image_get_os(hdr)); arch = image_get_arch_name(image_get_arch(hdr)); type = image_get_type_name(image_get_type(hdr)); comp = image_get_comp_name(image_get_comp(hdr)); printf ("%s %s %s (%s)\n", arch, os, type, comp); }
int spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); if (image_get_magic(header) == IH_MAGIC) { if (spl_image.flags & SPL_COPY_PAYLOAD_ONLY) { /* * On some system (e.g. powerpc), the load-address and * entry-point is located at address 0. We can't load * to 0-0x40. So skip header in this case. */ spl_image.load_addr = image_get_load(header); spl_image.entry_point = image_get_ep(header); spl_image.size = image_get_data_size(header); } else { spl_image.entry_point = image_get_load(header); /* Load including the header */ spl_image.load_addr = spl_image.entry_point - header_size; spl_image.size = image_get_data_size(header) + header_size; } spl_image.os = image_get_os(header); spl_image.name = image_get_name(header); debug("spl: payload image: %.*s load addr: 0x%x size: %d\n", (int)sizeof(spl_image.name), spl_image.name, spl_image.load_addr, spl_image.size); } else { #ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE /* * CONFIG_SPL_PANIC_ON_RAW_IMAGE is defined when the * code which loads images in SPL cannot guarantee that * absolutely all read errors will be reported. * An example is the LPC32XX MLC NAND driver, which * will consider that a completely unreadable NAND block * is bad, and thus should be skipped silently. */ panic("** no mkimage signature but raw image not supported"); #elif defined(CONFIG_SPL_ABORT_ON_RAW_IMAGE) /* Signature not found, proceed to other boot methods. */ return -EINVAL; #else /* Signature not found - assume u-boot.bin */ debug("mkimage signature not found - ih_magic = %x\n", header->ih_magic); spl_set_header_raw_uboot(); #endif } return 0; }
void spl_parse_image_header(const struct image_header *header) { u32 header_size = sizeof(struct image_header); if (image_get_magic(header) == IH_MAGIC) { if (spl_image.flags & SPL_COPY_PAYLOAD_ONLY) { /* * On some system (e.g. powerpc), the load-address and * entry-point is located at address 0. We can't load * to 0-0x40. So skip header in this case. */ spl_image.load_addr = image_get_load(header); spl_image.entry_point = image_get_ep(header); spl_image.size = image_get_data_size(header); } else { spl_image.entry_point = image_get_load(header); /* Load including the header */ spl_image.load_addr = spl_image.entry_point - header_size; spl_image.size = image_get_data_size(header) + header_size; } spl_image.os = image_get_os(header); spl_image.name = image_get_name(header); spl_image.crc = image_get_dcrc(header); spl_image.crc_size = image_get_data_size(header); debug("spl: payload image: %s load addr: 0x%x size: %d\n", spl_image.name, spl_image.load_addr, spl_image.size); } else { /* Signature not found - assume u-boot.bin */ debug("mkimage signature not found - ih_magic = %x\n", header->ih_magic); /* Let's assume U-Boot will not be more than 200 KB */ spl_image.size = CONFIG_SYS_MONITOR_LEN; spl_image.entry_point = CONFIG_SYS_UBOOT_START; spl_image.load_addr = CONFIG_SYS_TEXT_BASE; spl_image.os = IH_OS_U_BOOT; spl_image.name = "U-Boot"; spl_image.crc_size = 0; } }
static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { ulong mem_start; phys_size_t mem_size; void *os_hdr; int ret; memset ((void *)&images, 0, sizeof (images)); images.verify = getenv_yesno ("verify"); lmb_init(&images.lmb); mem_start = getenv_bootm_low(); mem_size = getenv_bootm_size(); lmb_add(&images.lmb, (phys_addr_t)mem_start, mem_size); arch_lmb_reserve(&images.lmb); board_lmb_reserve(&images.lmb); /* get kernel image header, start address and length */ os_hdr = boot_get_kernel (cmdtp, flag, argc, argv, &images, &images.os.image_start, &images.os.image_len); if (images.os.image_len == 0) { puts ("ERROR: can't get kernel image!\n"); return 1; } /* get image parameters */ switch (genimg_get_format (os_hdr)) { case IMAGE_FORMAT_LEGACY: images.os.type = image_get_type (os_hdr); images.os.comp = image_get_comp (os_hdr); images.os.os = image_get_os (os_hdr); images.os.end = image_get_image_end (os_hdr); images.os.load = image_get_load (os_hdr); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: if (fit_image_get_type (images.fit_hdr_os, images.fit_noffset_os, &images.os.type)) { puts ("Can't get image type!\n"); show_boot_progress (-109); return 1; } if (fit_image_get_comp (images.fit_hdr_os, images.fit_noffset_os, &images.os.comp)) { puts ("Can't get image compression!\n"); show_boot_progress (-110); return 1; } if (fit_image_get_os (images.fit_hdr_os, images.fit_noffset_os, &images.os.os)) { puts ("Can't get image OS!\n"); show_boot_progress (-111); return 1; } images.os.end = fit_get_end (images.fit_hdr_os); if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os, &images.os.load)) { puts ("Can't get image load address!\n"); show_boot_progress (-112); return 1; } break; #endif default: puts ("ERROR: unknown image format type!\n"); return 1; } /* find kernel entry point */ if (images.legacy_hdr_valid) { images.ep = image_get_ep (&images.legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images.fit_uname_os) { ret = fit_image_get_entry (images.fit_hdr_os, images.fit_noffset_os, &images.ep); if (ret) { puts ("Can't get entry point property!\n"); return 1; } #endif } else { puts ("Could not find kernel entry point!\n"); return 1; } if (images.os.os == IH_OS_LINUX) { /* find ramdisk */ ret = boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH, &images.rd_start, &images.rd_end); if (ret) { puts ("Ramdisk image is corrupt or invalid\n"); return 1; } #if defined(CONFIG_OF_LIBFDT) #if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC) /* find flattened device tree */ ret = boot_get_fdt (flag, argc, argv, &images, &images.ft_addr, &images.ft_len); if (ret) { puts ("Could not find a valid device tree\n"); return 1; } set_working_fdt_addr(images.ft_addr); #endif #endif } images.os.start = (ulong)os_hdr; images.state = BOOTM_STATE_START; return 0; }
int spl_parse_image_header(struct spl_image_info *spl_image, const struct image_header *header) { if (image_get_magic(header) == IH_MAGIC) { #ifdef CONFIG_SPL_LEGACY_IMAGE_SUPPORT u32 header_size = sizeof(struct image_header); if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY) { /* * On some system (e.g. powerpc), the load-address and * entry-point is located at address 0. We can't load * to 0-0x40. So skip header in this case. */ spl_image->load_addr = image_get_load(header); spl_image->entry_point = image_get_ep(header); spl_image->size = image_get_data_size(header); } else { spl_image->entry_point = image_get_load(header); /* Load including the header */ spl_image->load_addr = spl_image->entry_point - header_size; spl_image->size = image_get_data_size(header) + header_size; } spl_image->os = image_get_os(header); spl_image->name = image_get_name(header); debug("spl: payload image: %.*s load addr: 0x%lx size: %d\n", (int)sizeof(spl_image->name), spl_image->name, spl_image->load_addr, spl_image->size); #else /* LEGACY image not supported */ debug("Legacy boot image support not enabled, proceeding to other boot methods"); return -EINVAL; #endif } else { #ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE /* * CONFIG_SPL_PANIC_ON_RAW_IMAGE is defined when the * code which loads images in SPL cannot guarantee that * absolutely all read errors will be reported. * An example is the LPC32XX MLC NAND driver, which * will consider that a completely unreadable NAND block * is bad, and thus should be skipped silently. */ panic("** no mkimage signature but raw image not supported"); #endif #ifdef CONFIG_SPL_OS_BOOT ulong start, end; if (!bootz_setup((ulong)header, &start, &end)) { spl_image->name = "Linux"; spl_image->os = IH_OS_LINUX; spl_image->load_addr = CONFIG_SYS_LOAD_ADDR; spl_image->entry_point = CONFIG_SYS_LOAD_ADDR; spl_image->size = end - start; debug("spl: payload zImage, load addr: 0x%lx size: %d\n", spl_image->load_addr, spl_image->size); return 0; } #endif #ifdef CONFIG_SPL_RAW_IMAGE_SUPPORT /* Signature not found - assume u-boot.bin */ debug("mkimage signature not found - ih_magic = %x\n", header->ih_magic); spl_set_header_raw_uboot(spl_image); #else /* RAW image not supported, proceed to other boot methods. */ debug("Raw boot image support not enabled, proceeding to other boot methods"); return -EINVAL; #endif } return 0; }
static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { const void *os_hdr; int ret; memset((void *)&images, 0, sizeof(images)); images.verify = getenv_yesno("verify"); boot_start_lmb(&images); bootstage_mark_name(BOOTSTAGE_ID_BOOTM_START, "bootm_start"); /* get kernel image header, start address and length */ os_hdr = boot_get_kernel(cmdtp, flag, argc, argv, &images, &images.os.image_start, &images.os.image_len); if (images.os.image_len == 0) { puts("ERROR: can't get kernel image!\n"); return 1; } /* get image parameters */ switch (genimg_get_format(os_hdr)) { case IMAGE_FORMAT_LEGACY: images.os.type = image_get_type(os_hdr); images.os.comp = image_get_comp(os_hdr); images.os.os = image_get_os(os_hdr); images.os.end = image_get_image_end(os_hdr); images.os.load = image_get_load(os_hdr); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: if (fit_image_get_type(images.fit_hdr_os, images.fit_noffset_os, &images.os.type)) { puts("Can't get image type!\n"); bootstage_error(BOOTSTAGE_ID_FIT_TYPE); return 1; } if (fit_image_get_comp(images.fit_hdr_os, images.fit_noffset_os, &images.os.comp)) { puts("Can't get image compression!\n"); bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION); return 1; } if (fit_image_get_os(images.fit_hdr_os, images.fit_noffset_os, &images.os.os)) { puts("Can't get image OS!\n"); bootstage_error(BOOTSTAGE_ID_FIT_OS); return 1; } images.os.end = fit_get_end(images.fit_hdr_os); if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os, &images.os.load)) { puts("Can't get image load address!\n"); bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR); return 1; } break; #endif default: puts("ERROR: unknown image format type!\n"); return 1; } /* find kernel entry point */ if (images.legacy_hdr_valid) { images.ep = image_get_ep(&images.legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images.fit_uname_os) { ret = fit_image_get_entry(images.fit_hdr_os, images.fit_noffset_os, &images.ep); if (ret) { puts("Can't get entry point property!\n"); return 1; } #endif } else { puts("Could not find kernel entry point!\n"); return 1; } if (images.os.type == IH_TYPE_KERNEL_NOLOAD) { images.os.load = images.os.image_start; images.ep += images.os.load; } if (((images.os.type == IH_TYPE_KERNEL) || (images.os.type == IH_TYPE_KERNEL_NOLOAD) || (images.os.type == IH_TYPE_MULTI)) && (images.os.os == IH_OS_LINUX)) { /* find ramdisk */ ret = boot_get_ramdisk(argc, argv, &images, IH_INITRD_ARCH, &images.rd_start, &images.rd_end); if (ret) { puts("Ramdisk image is corrupt or invalid\n"); return 1; } #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ ret = boot_get_fdt(flag, argc, argv, &images, &images.ft_addr, &images.ft_len); if (ret) { puts("Could not find a valid device tree\n"); return 1; } set_working_fdt_addr(images.ft_addr); #endif } images.os.start = (ulong)os_hdr; images.state = BOOTM_STATE_START; return 0; }
static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { const void *os_hdr; bool ep_found = false; /* get kernel image header, start address and length */ os_hdr = boot_get_kernel(cmdtp, flag, argc, argv, &images, &images.os.image_start, &images.os.image_len); if (images.os.image_len == 0) { puts("ERROR: can't get kernel image!\n"); return 1; } /* get image parameters */ switch (genimg_get_format(os_hdr)) { case IMAGE_FORMAT_LEGACY: images.os.type = image_get_type(os_hdr); images.os.comp = image_get_comp(os_hdr); images.os.os = image_get_os(os_hdr); images.os.end = image_get_image_end(os_hdr); images.os.load = image_get_load(os_hdr); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: if (fit_image_get_type(images.fit_hdr_os, images.fit_noffset_os, &images.os.type)) { puts("Can't get image type!\n"); bootstage_error(BOOTSTAGE_ID_FIT_TYPE); return 1; } if (fit_image_get_comp(images.fit_hdr_os, images.fit_noffset_os, &images.os.comp)) { puts("Can't get image compression!\n"); bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION); return 1; } if (fit_image_get_os(images.fit_hdr_os, images.fit_noffset_os, &images.os.os)) { puts("Can't get image OS!\n"); bootstage_error(BOOTSTAGE_ID_FIT_OS); return 1; } images.os.end = fit_get_end(images.fit_hdr_os); if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os, &images.os.load)) { puts("Can't get image load address!\n"); bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR); return 1; } break; #endif #ifdef CONFIG_ANDROID_BOOT_IMAGE case IMAGE_FORMAT_ANDROID: images.os.type = IH_TYPE_KERNEL; images.os.comp = IH_COMP_NONE; images.os.os = IH_OS_LINUX; images.ep = images.os.load; ep_found = true; images.os.end = android_image_get_end(os_hdr); images.os.load = android_image_get_kload(os_hdr); break; #endif default: puts("ERROR: unknown image format type!\n"); return 1; } /* find kernel entry point */ if (images.legacy_hdr_valid) { images.ep = image_get_ep(&images.legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images.fit_uname_os) { int ret; ret = fit_image_get_entry(images.fit_hdr_os, images.fit_noffset_os, &images.ep); if (ret) { puts("Can't get entry point property!\n"); return 1; } #endif } else if (!ep_found) { puts("Could not find kernel entry point!\n"); return 1; } if (images.os.type == IH_TYPE_KERNEL_NOLOAD) { images.os.load = images.os.image_start; images.ep += images.os.load; } images.os.start = (ulong)os_hdr; return 0; }
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { image_header_t *hdr; ulong addr; ulong iflag; const char *type_name; uint unc_len = CONFIG_SYS_BOOTM_LEN; uint8_t comp, type, os; void *os_hdr; ulong os_data, os_len; ulong image_start, image_end; ulong load_start, load_end; ulong mem_start; phys_size_t mem_size; struct lmb lmb; #if defined(CONFIG_SECURE_BOOT) int rv; #endif #if defined(CONFIG_SECURE_BOOT) rv = Check_Signature( (SecureBoot_CTX *)SECURE_BOOT_CONTEXT_ADDR, (unsigned char*)CONFIG_SECURE_KERNEL_BASE, CONFIG_SECURE_KERNEL_SIZE-128, (unsigned char*)(CONFIG_SECURE_KERNEL_BASE+CONFIG_SECURE_KERNEL_SIZE-128), 128 ); if(rv != SB_OK) { printf("Kernel Integrity check fail\nSystem Halt...."); while(1); } printf("Kernel Integirty check success.\n"); rv = Check_Signature( (SecureBoot_CTX *)SECURE_BOOT_CONTEXT_ADDR, (unsigned char*)CONFIG_SECURE_ROOTFS_BASE, CONFIG_SECURE_ROOTFS_SIZE-128, (unsigned char*)(CONFIG_SECURE_ROOTFS_BASE+CONFIG_SECURE_ROOTFS_SIZE-128), 128 ); if(rv != SB_OK) { printf("rootfs Integrity check fail\nSystem Halt...."); while(1); } printf("rootfs Integirty check success.\n"); #endif memset ((void *)&images, 0, sizeof (images)); images.verify = getenv_yesno ("verify"); // images.lmb = &lmb; memcpy (&images.lmb, &lmb, sizeof(struct lmb)); lmb_init(&lmb); mem_start = getenv_bootm_low(); mem_size = getenv_bootm_size(); lmb_add(&lmb, (phys_addr_t)mem_start, mem_size); board_lmb_reserve(&lmb); #ifdef CONFIG_ZIMAGE_BOOT #define LINUX_ZIMAGE_MAGIC 0x016f2818 /* find out kernel image address */ if (argc < 2) { addr = load_addr; debug ("* kernel: default image load address = 0x%08lx\n", load_addr); } else { addr = simple_strtoul(argv[1], NULL, 16); //debug ("* kernel: cmdline image address = 0x%08lx\n", img_addr); } if (*(ulong *)(addr + 9*4) == LINUX_ZIMAGE_MAGIC) { printf("Boot with zImage\n"); addr = virt_to_phys(addr); hdr = (image_header_t *)addr; hdr->ih_os = IH_OS_LINUX; hdr->ih_ep = ntohl(addr); 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; goto after_header_check; } #endif /* get kernel image header, start address and length */ os_hdr = boot_get_kernel (cmdtp, flag, argc, argv, &images, &os_data, &os_len); if (os_len == 0) { puts ("ERROR: can't get kernel image!\n"); return 1; } /* get image parameters */ switch (genimg_get_format (os_hdr)) { case IMAGE_FORMAT_LEGACY: type = image_get_type (os_hdr); comp = image_get_comp (os_hdr); os = image_get_os (os_hdr); image_end = image_get_image_end (os_hdr); load_start = image_get_load (os_hdr); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: if (fit_image_get_type (images.fit_hdr_os, images.fit_noffset_os, &type)) { puts ("Can't get image type!\n"); show_boot_progress (-109); return 1; } if (fit_image_get_comp (images.fit_hdr_os, images.fit_noffset_os, &comp)) { puts ("Can't get image compression!\n"); show_boot_progress (-110); return 1; } if (fit_image_get_os (images.fit_hdr_os, images.fit_noffset_os, &os)) { puts ("Can't get image OS!\n"); show_boot_progress (-111); return 1; } image_end = fit_get_end (images.fit_hdr_os); if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os, &load_start)) { puts ("Can't get image load address!\n"); show_boot_progress (-112); return 1; } break; #endif default: puts ("ERROR: unknown image format type!\n"); return 1; } image_start = (ulong)os_hdr; load_end = 0; type_name = genimg_get_type_name (type); /* * 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(); #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 #ifdef CONFIG_AMIGAONEG3SE /* * We've possible left the caches enabled during * bios emulation, so turn them off again */ icache_disable(); invalidate_l1_instruction_cache(); flush_data_cache(); dcache_disable(); #endif switch (comp) { case IH_COMP_NONE: if (load_start == (ulong)os_hdr) { printf (" XIP %s ... ", type_name); } else { printf (" Loading %s ... ", type_name); memmove_wd ((void *)load_start, (void *)os_data, os_len, CHUNKSZ); } load_end = load_start + os_len; puts("OK\n"); break; case IH_COMP_GZIP: printf (" Uncompressing %s ... ", type_name); if (gunzip ((void *)load_start, unc_len, (uchar *)os_data, &os_len) != 0) { puts ("GUNZIP: uncompress or overwrite error " "- must RESET board to recover\n"); show_boot_progress (-6); do_reset (cmdtp, flag, argc, argv); } load_end = load_start + os_len; break; #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_start, &unc_len, (char *)os_data, os_len, CFG_MALLOC_LEN < (4096 * 1024), 0); if (i != BZ_OK) { printf ("BUNZIP2: uncompress or overwrite error %d " "- must RESET board to recover\n", i); show_boot_progress (-6); do_reset (cmdtp, flag, argc, argv); } load_end = load_start + unc_len; break; #endif /* CONFIG_BZIP2 */ default: if (iflag) enable_interrupts(); printf ("Unimplemented compression type %d\n", comp); show_boot_progress (-7); return 1; } puts ("OK\n"); debug (" kernel loaded at 0x%08lx, end = 0x%08lx\n", load_start, load_end); show_boot_progress (7); if ((load_start < image_end) && (load_end > image_start)) { debug ("image_start = 0x%lX, image_end = 0x%lx\n", image_start, image_end); debug ("load_start = 0x%lx, load_end = 0x%lx\n", load_start, load_end); 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"); } else { puts ("ERROR: new format image overwritten - " "must RESET the board to recover\n"); show_boot_progress (-113); do_reset (cmdtp, flag, argc, argv); } } show_boot_progress (8); lmb_reserve(&lmb, load_start, (load_end - load_start)); #if defined(CONFIG_ZIMAGE_BOOT) after_header_check: os = hdr->ih_os; #endif switch (os) { default: /* handled by (original) Linux case */ case IH_OS_LINUX: #ifdef CONFIG_SILENT_CONSOLE fixup_silent_linux(); #endif do_bootm_linux (flag, argc, argv, &images); break; #ifdef CONFIG_BOOTM_NETBSD case IH_OS_NETBSD: do_bootm_netbsd (flag, argc, argv, &images); break; #endif #ifdef CONFIG_LYNXKDI case IH_OS_LYNXOS: do_bootm_lynxkdi (flag, argc, argv, &images); break; #endif #ifdef CONFIG_BOOTM_RTEMS case IH_OS_RTEMS: do_bootm_rtems (flag, argc, argv, &images); break; #endif /* #if defined(CONFIG_CMD_ELF) case IH_OS_VXWORKS: do_bootm_vxworks (cmdtp, flag, argc, argv, &images); break; case IH_OS_QNX: do_bootm_qnxelf (cmdtp, flag, argc, argv, &images); break; #endif */ #ifdef CONFIG_ARTOS case IH_OS_ARTOS: do_bootm_artos (cmdtp, flag, argc, argv, &images); break; #endif } show_boot_progress (-9); #ifdef DEBUG puts ("\n## Control returned to monitor - resetting...\n"); do_reset (cmdtp, flag, argc, argv); #endif if (iflag) enable_interrupts(); return 1; }
static int bootm_find_os(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { const void *os_hdr; bool ep_found = false; int ret; /* get kernel image header, start address and length */ os_hdr = boot_get_kernel(cmdtp, flag, argc, argv, &images, &images.os.image_start, &images.os.image_len); if (images.os.image_len == 0) { puts("ERROR: can't get kernel image!\n"); return 1; } /* get image parameters */ switch (genimg_get_format(os_hdr)) { #if defined(CONFIG_IMAGE_FORMAT_LEGACY) case IMAGE_FORMAT_LEGACY: images.os.type = image_get_type(os_hdr); images.os.comp = image_get_comp(os_hdr); images.os.os = image_get_os(os_hdr); images.os.end = image_get_image_end(os_hdr); images.os.load = image_get_load(os_hdr); images.os.arch = image_get_arch(os_hdr); break; #endif #if IMAGE_ENABLE_FIT case IMAGE_FORMAT_FIT: if (fit_image_get_type(images.fit_hdr_os, images.fit_noffset_os, &images.os.type)) { puts("Can't get image type!\n"); bootstage_error(BOOTSTAGE_ID_FIT_TYPE); return 1; } if (fit_image_get_comp(images.fit_hdr_os, images.fit_noffset_os, &images.os.comp)) { puts("Can't get image compression!\n"); bootstage_error(BOOTSTAGE_ID_FIT_COMPRESSION); return 1; } if (fit_image_get_os(images.fit_hdr_os, images.fit_noffset_os, &images.os.os)) { puts("Can't get image OS!\n"); bootstage_error(BOOTSTAGE_ID_FIT_OS); return 1; } if (fit_image_get_arch(images.fit_hdr_os, images.fit_noffset_os, &images.os.arch)) { puts("Can't get image ARCH!\n"); return 1; } images.os.end = fit_get_end(images.fit_hdr_os); if (fit_image_get_load(images.fit_hdr_os, images.fit_noffset_os, &images.os.load)) { puts("Can't get image load address!\n"); bootstage_error(BOOTSTAGE_ID_FIT_LOADADDR); return 1; } break; #endif #ifdef CONFIG_ANDROID_BOOT_IMAGE case IMAGE_FORMAT_ANDROID: images.os.type = IH_TYPE_KERNEL; images.os.comp = IH_COMP_NONE; images.os.os = IH_OS_LINUX; images.os.end = android_image_get_end(os_hdr); images.os.load = android_image_get_kload(os_hdr); images.ep = images.os.load; ep_found = true; break; #endif default: puts("ERROR: unknown image format type!\n"); return 1; } /* If we have a valid setup.bin, we will use that for entry (x86) */ if (images.os.arch == IH_ARCH_I386 || images.os.arch == IH_ARCH_X86_64) { ulong len; ret = boot_get_setup(&images, IH_ARCH_I386, &images.ep, &len); if (ret < 0 && ret != -ENOENT) { puts("Could not find a valid setup.bin for x86\n"); return 1; } /* Kernel entry point is the setup.bin */ } else if (images.legacy_hdr_valid) { images.ep = image_get_ep(&images.legacy_hdr_os_copy); #if IMAGE_ENABLE_FIT } else if (images.fit_uname_os) { int ret; ret = fit_image_get_entry(images.fit_hdr_os, images.fit_noffset_os, &images.ep); if (ret) { puts("Can't get entry point property!\n"); return 1; } #endif } else if (!ep_found) { puts("Could not find kernel entry point!\n"); return 1; } if (images.os.type == IH_TYPE_KERNEL_NOLOAD) { if (CONFIG_IS_ENABLED(CMD_BOOTI) && images.os.arch == IH_ARCH_ARM64) { ulong image_addr; ulong image_size; ret = booti_setup(images.os.image_start, &image_addr, &image_size, true); if (ret != 0) return 1; images.os.type = IH_TYPE_KERNEL; images.os.load = image_addr; images.ep = image_addr; } else { images.os.load = images.os.image_start; images.ep += images.os.image_start; } } images.os.start = map_to_sysmem(os_hdr); return 0; }
static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { void *os_hdr; int ret; #if defined(CONFIG_ANDROID_IMG) void *temp_os_hdr = NULL; boot_img_hdr *temp_android_hdr = NULL; #endif memset ((void *)&images, 0, sizeof (images)); images.verify = getenv_yesno ("verify"); bootm_start_lmb(); /* get kernel image header, start address and length */ os_hdr = boot_get_kernel (cmdtp, flag, argc, argv, &images, &images.os.image_start, &images.os.image_len); if (images.os.image_len == 0) { puts ("ERROR: can't get kernel image!\n"); return 1; } /* get image parameters */ switch (genimg_get_format (os_hdr)) { case IMAGE_FORMAT_LEGACY: images.os.type = image_get_type (os_hdr); images.os.comp = image_get_comp (os_hdr); images.os.os = image_get_os (os_hdr); images.os.end = image_get_image_end (os_hdr); images.os.load = image_get_load (os_hdr); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: if (fit_image_get_type (images.fit_hdr_os, images.fit_noffset_os, &images.os.type)) { puts ("Can't get image type!\n"); show_boot_progress (-109); return 1; } if (fit_image_get_comp (images.fit_hdr_os, images.fit_noffset_os, &images.os.comp)) { puts ("Can't get image compression!\n"); show_boot_progress (-110); return 1; } if (fit_image_get_os (images.fit_hdr_os, images.fit_noffset_os, &images.os.os)) { puts ("Can't get image OS!\n"); show_boot_progress (-111); return 1; } images.os.end = fit_get_end (images.fit_hdr_os); if (fit_image_get_load (images.fit_hdr_os, images.fit_noffset_os, &images.os.load)) { puts ("Can't get image load address!\n"); show_boot_progress (-112); return 1; } break; #endif #if defined(CONFIG_ANDROID_IMG) case IMAGE_FORMAT_ANDROID: temp_os_hdr = os_hdr + 0x800;//shift 0x800 Android format head temp_android_hdr = (void *) os_hdr; images.os.type = image_get_type (temp_os_hdr); images.os.comp = image_get_comp (temp_os_hdr); images.os.os = image_get_os (temp_os_hdr); images.os.end = image_get_image_end (temp_os_hdr); images.os.load = image_get_load (temp_os_hdr); images.rd_start = ((ulong)temp_android_hdr->kernel_size + 0x800 + (ulong)os_hdr + ((ulong)temp_android_hdr->page_size - 1)) & (~((ulong)temp_android_hdr->page_size - 1)); images.rd_end = images.rd_start + (ulong)temp_android_hdr->ramdisk_size; printf(" Ramdisk start addr = 0x%x, len = 0x%x\n",images.rd_start,temp_android_hdr->ramdisk_size ); #if defined(CONFIG_OF_LIBFDT) if(images.ft_len = (ulong)temp_android_hdr->second_size) { fdt_addr = (images.rd_end + ((ulong)temp_android_hdr->page_size - 1)) & (~((ulong)temp_android_hdr->page_size - 1)); /*get_multi_dt_entry, compatible with single dt*/ fdt_addr = get_multi_dt_entry(fdt_addr); images.ft_addr = (char *)fdt_addr; images.ft_len = fdt_totalsize(fdt_addr); printf(" Flat device tree start addr = 0x%x, len = 0x%x magic=0x%x\n", (int *)images.ft_addr,images.ft_len,*(unsigned int*)images.ft_addr); } #endif break; #endif default: puts ("ERROR: unknown image format type!\n"); return 1; } /* find kernel entry point */ if (images.legacy_hdr_valid) { images.ep = image_get_ep (&images.legacy_hdr_os_copy); #if defined(CONFIG_FIT) } else if (images.fit_uname_os) { ret = fit_image_get_entry (images.fit_hdr_os, images.fit_noffset_os, &images.ep); if (ret) { puts ("Can't get entry point property!\n"); return 1; } #endif } else { puts ("Could not find kernel entry point!\n"); return 1; } if (((images.os.type == IH_TYPE_KERNEL) || (images.os.type == IH_TYPE_MULTI)) && (images.os.os == IH_OS_LINUX)) { /* find ramdisk */ #ifndef CONFIG_ANDROID_IMG #if defined(CONFIG_AML_MESON_FIT) //call boot_get_ramdisk() here for get ramdisk start addr boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH, &images.rd_start, &images.rd_end); #endif #endif #if defined(CONFIG_ANDROID_IMG) if(!images.rd_start) #endif { ret = boot_get_ramdisk (argc, argv, &images, IH_INITRD_ARCH, &images.rd_start, &images.rd_end); if (ret) { puts ("Ramdisk image is corrupt or invalid\n"); return 1; } } #if defined(CONFIG_OF_LIBFDT) /* find flattened device tree */ #if defined(CONFIG_ANDROID_IMG) if(!images.ft_addr) #endif { ret = boot_get_fdt (flag, argc, argv, &images, &images.ft_addr, &images.ft_len); if (ret) { puts ("Could not find a valid device tree\n"); return 1; } } set_working_fdt_addr(images.ft_addr); #endif } #if defined(CONFIG_ANDROID_IMG) images.os.start = (ulong)temp_os_hdr; #else images.os.start = (ulong)os_hdr; #endif images.state = BOOTM_STATE_START; return 0; }