static int spl_ram_load_image(void) { struct image_header *header; header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS; if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) { struct spl_load_info load; debug("Found FIT\n"); load.bl_len = 1; load.read = spl_ram_load_read; spl_load_simple_fit(&load, 0, header); } else { debug("Legacy image\n"); /* * Get the header. It will point to an address defined by * handoff which will tell where the image located inside * the flash. For now, it will temporary fixed to address * pointed by U-Boot. */ header = (struct image_header *) (CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); spl_parse_image_header(header); } return 0; }
/* verify and prepare for booting of a legacy kernel */ int legacy_boot(void *kernel, const char *cmd_line_buf) { const image_header_t *hdr = kernel; bootm_header_t bootm_header; memset(&bootm_header, 0, sizeof(bootm_header)); if (image_get_magic(hdr) != IH_MAGIC) return 1; if (!image_check_hcrc(hdr)) { printf("Bad Header CRC\n"); return 1; } if (!image_check_dcrc(hdr)) { printf("Bad Data CRC\n"); return 1; } bootm_header.os.type = image_get_type(hdr); bootm_header.os.comp = image_get_comp(hdr); bootm_header.os.end = (uint32_t)hdr + image_get_size(hdr) + sizeof(*hdr); bootm_header.os.load = image_get_load(hdr); bootm_header.os.start = (uint32_t) hdr; bootm_header.os.image_start = (uint32_t)(hdr + 1); bootm_header.os.image_len = image_get_size(hdr); bootm_header.ep = image_get_ep(hdr); bootm_header.cmdline = cmd_line_buf; return start_legacy_kernel(&bootm_header); }
static int spl_nand_load_element(int offset, struct image_header *header) { int err; err = nand_spl_load_image(offset, sizeof(*header), (void *)header); if (err) return err; if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) { struct spl_load_info load; debug("Found FIT\n"); load.dev = NULL; load.priv = NULL; load.filename = NULL; load.bl_len = 1; load.read = spl_nand_fit_read; return spl_load_simple_fit(&load, offset, header); } else { err = spl_parse_image_header(header); if (err) return err; return nand_spl_load_image(offset, spl_image.size, (void *)(ulong)spl_image.load_addr); } }
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 mmc_load_image_raw(struct mmc *mmc, unsigned long sector) { unsigned long err; u32 image_size_sectors; struct image_header *header; header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); /* read image header to find the image size & load address */ err = mmc->block_dev.block_read(0, sector, 1, header); if (err == 0) goto end; if (image_get_magic(header) != IH_MAGIC) return -1; spl_parse_image_header(header); /* convert size to sectors - round up */ image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / mmc->read_bl_len; /* Read the header too to avoid extra memcpy */ err = mmc->block_dev.block_read(0, sector, image_size_sectors, (void *)spl_image.load_addr); end: #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT if (err == 0) printf("spl: mmc blk read err - %lu\n", err); #endif return (err == 0); }
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; }
static int image_verify_header(char *ptr, int fd) { int len, nread; char *data; uint32_t checksum; image_header_t *hdr = (image_header_t *)ptr; char buf[PAGE_SIZE]; if (image_get_magic(hdr) != IH_MAGIC) return 0; data = (char *)hdr; len = image_get_header_size(); checksum = image_get_hcrc(hdr); hdr->ih_hcrc = htonl(0); /* clear for re-calculation */ if (crc32(0, data, len) != checksum) { fprintf(stderr, "%s: Maybe image found but it has bad header checksum!\n", cmdname); return 0; } len = image_get_size(hdr); checksum = 0; while (len > 0) { nread = read(fd, buf, MIN(len,PAGE_SIZE)); if (nread != MIN(len,PAGE_SIZE)) { fprintf(stderr, "%s: Error while reading: %s\n", cmdname, strerror(errno)); exit(EXIT_FAILURE); } checksum = crc32(checksum, buf, nread); len -= nread; } if (checksum != image_get_dcrc(hdr)) { fprintf (stderr, "%s: Maybe image found but it has corrupted data!\n", cmdname); return 0; } return 1; }
int spl_load_image_fat(struct spl_image_info *spl_image, struct blk_desc *block_dev, int partition, const char *filename) { int err; struct image_header *header; err = spl_register_fat_device(block_dev, partition); if (err) goto end; header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - sizeof(struct image_header)); err = file_fat_read(filename, header, sizeof(struct image_header)); if (err <= 0) goto end; if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) { struct spl_load_info load; debug("Found FIT\n"); load.read = spl_fit_read; load.bl_len = 1; load.filename = (void *)filename; load.priv = NULL; return spl_load_simple_fit(spl_image, &load, 0, header); } else { err = spl_parse_image_header(spl_image, header); if (err) goto end; err = file_fat_read(filename, (u8 *)(uintptr_t)spl_image->load_addr, 0); } end: #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT if (err <= 0) printf("%s: error reading image %s, err - %d\n", __func__, filename, err); #endif return (err <= 0); }
static int spl_ram_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { struct image_header *header; header = (struct image_header *)CONFIG_SPL_LOAD_FIT_ADDRESS; #if CONFIG_IS_ENABLED(DFU_SUPPORT) if (bootdev->boot_device == BOOT_DEVICE_DFU) spl_dfu_cmd(0, "dfu_alt_info_ram", "ram", "0"); #endif if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) { struct spl_load_info load; debug("Found FIT\n"); load.bl_len = 1; load.read = spl_ram_load_read; spl_load_simple_fit(spl_image, &load, 0, header); } else { ulong u_boot_pos = binman_sym(ulong, u_boot_any, pos); debug("Legacy image\n"); /* * Get the header. It will point to an address defined by * handoff which will tell where the image located inside * the flash. */ debug("u_boot_pos = %lx\n", u_boot_pos); if (u_boot_pos == BINMAN_SYM_MISSING) { /* * No binman support or no information. For now, fix it * to the address pointed to by U-Boot. */ u_boot_pos = CONFIG_SYS_TEXT_BASE - sizeof(struct image_header); } header = (struct image_header *)map_sysmem(u_boot_pos, 0); spl_parse_image_header(spl_image, header); } return 0; }
static int spl_net_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { struct image_header *header = (struct image_header *)load_addr; int rv; env_init(); env_relocate(); env_set("autoload", "yes"); rv = eth_initialize(); if (rv == 0) { printf("No Ethernet devices found\n"); return -ENODEV; } if (bootdev->boot_device_name) env_set("ethact", bootdev->boot_device_name); rv = net_loop(BOOTP); if (rv < 0) { printf("Problem booting with BOOTP\n"); return rv; } if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) { struct spl_load_info load; debug("Found FIT\n"); load.bl_len = 1; load.read = spl_net_load_read; rv = spl_load_simple_fit(spl_image, &load, 0, header); } else { debug("Legacy image\n"); rv = spl_parse_image_header(spl_image, header); if (rv) return rv; memcpy((void *)spl_image->load_addr, header, spl_image->size); } return rv; }
int spl_net_load_image(const char *device) { struct image_header *header; int rv; env_init(); env_relocate(); setenv("autoload", "yes"); if (IS_ENABLED(CONFIG_SPL_LOAD_FIT)) load_addr = CONFIG_SPL_LOAD_FIT_ADDRESS; else load_addr = CONFIG_SYS_TEXT_BASE - sizeof(struct image_header); rv = eth_initialize(); if (rv == 0) { printf("No Ethernet devices found\n"); return -ENODEV; } if (device) setenv("ethact", device); rv = net_loop(BOOTP); if (rv < 0) { printf("Problem booting with BOOTP\n"); return rv; } header = (struct image_header *)load_addr; if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) { struct spl_load_info load; debug("Found FIT\n"); load.bl_len = 1; load.read = spl_net_load_read; spl_load_simple_fit(&load, 0, header); } else { spl_parse_image_header((struct image_header *)load_addr); } 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; } }
void *locate_dtb_in_fit(const void *fit) { struct image_header *header; int size; int ret; size = fdt_totalsize(fit); size = (size + 3) & ~3; header = (struct image_header *)fit; if (image_get_magic(header) != FDT_MAGIC) { debug("No FIT image appended to U-boot\n"); return NULL; } ret = fdt_offset(fit); if (ret < 0) return NULL; else return (void *)fit+size+ret; }
static int spl_spi_load_image(struct spl_image_info *spl_image, struct spl_boot_device *bootdev) { int ret = 0; struct image_header *header; header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); spi0_init(); spi0_read_data((void *)header, CONFIG_SYS_SPI_U_BOOT_OFFS, 0x40); if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && image_get_magic(header) == FDT_MAGIC) { struct spl_load_info load; debug("Found FIT image\n"); load.dev = NULL; load.priv = NULL; load.filename = NULL; load.bl_len = 1; load.read = spi_load_read; ret = spl_load_simple_fit(spl_image, &load, CONFIG_SYS_SPI_U_BOOT_OFFS, header); } else { ret = spl_parse_image_header(spl_image, header); if (ret) return ret; spi0_read_data((void *)spl_image->load_addr, CONFIG_SYS_SPI_U_BOOT_OFFS, spl_image->size); } spi0_deinit(); return ret; }
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; }
int au_check_header_valid(int idx, long nbytes) { image_header_t *hdr; unsigned long checksum, fsize; hdr = (image_header_t *)LOAD_ADDR; #if defined(CONFIG_FIT) if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } #endif /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC); printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_ARM); printf("size %#x %#lx ", image_get_data_size (hdr), nbytes); printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL); #endif if (nbytes < image_get_header_size ()) { printf ("Image %s bad header SIZE\n", aufile[idx]); ausize[idx] = 0; return -1; } if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_PPC)) { printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]); ausize[idx] = 0; return -1; } /* check the hdr CRC */ if (!image_check_hcrc (hdr)) { printf ("Image %s bad header checksum\n", aufile[idx]); ausize[idx] = 0; return -1; } /* check the type - could do this all in one gigantic if() */ if ((idx == IDX_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) { printf ("Image %s wrong type\n", aufile[idx]); ausize[idx] = 0; return -1; } if ((idx == IDX_KERNEL) && !image_check_type (hdr, IH_TYPE_KERNEL)) { printf ("Image %s wrong type\n", aufile[idx]); ausize[idx] = 0; return -1; } if ((idx == IDX_ROOTFS) && (!image_check_type (hdr, IH_TYPE_RAMDISK) && !image_check_type (hdr, IH_TYPE_FILESYSTEM))) { printf ("Image %s wrong type\n", aufile[idx]); ausize[idx] = 0; return -1; } /* recycle checksum */ checksum = image_get_data_size (hdr); fsize = checksum + image_get_header_size (); /* for kernel and ramdisk the image header must also fit into flash */ if (idx == IDX_KERNEL || image_check_type (hdr, IH_TYPE_RAMDISK)) checksum += image_get_header_size (); /* check the size does not exceed space in flash. HUSH scripts */ if ((ausize[idx] != 0) && (ausize[idx] < checksum)) { printf ("Image %s is bigger than FLASH\n", aufile[idx]); ausize[idx] = 0; return -1; } /* Update with the real filesize */ ausize[idx] = fsize; return checksum; /* return size to be written to flash */ }
int au_check_header_valid(int idx, long nbytes) { image_header_t *hdr; unsigned long checksum; unsigned char buf[4]; hdr = (image_header_t *)LOAD_ADDR; #if defined(CONFIG_FIT) if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } #endif /* check the easy ones first */ #undef CHECK_VALID_DEBUG #ifdef CHECK_VALID_DEBUG printf("magic %#x %#x ", image_get_magic (hdr), IH_MAGIC); printf("arch %#x %#x ", image_get_arch (hdr), IH_ARCH_ARM); printf("size %#x %#lx ", image_get_data_size (hdr), nbytes); printf("type %#x %#x ", image_get_type (hdr), IH_TYPE_KERNEL); #endif if (nbytes < image_get_header_size ()) { printf ("Image %s bad header SIZE\n", aufile[idx]); return -1; } if (!image_check_magic (hdr) || !image_check_arch (hdr, IH_ARCH_ARM)) { printf ("Image %s bad MAGIC or ARCH\n", aufile[idx]); return -1; } /* check the hdr CRC */ if (!image_check_hcrc (hdr)) { printf ("Image %s bad header checksum\n", aufile[idx]); return -1; } /* check the type - could do this all in one gigantic if() */ if ((idx == IDX_FIRMWARE) && !image_check_type (hdr, IH_TYPE_FIRMWARE)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } if ((idx == IDX_KERNEL) && !image_check_type (hdr, IH_TYPE_KERNEL)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } if ((idx == IDX_DISK) && !image_check_type (hdr, IH_TYPE_FILESYSTEM)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } if ((idx == IDX_APP) && !image_check_type (hdr, IH_TYPE_RAMDISK) && !image_check_type (hdr, IH_TYPE_FILESYSTEM)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } if ((idx == IDX_PREPARE || idx == IDX_PREINST || idx == IDX_POSTINST) && !image_check_type (hdr, IH_TYPE_SCRIPT)) { printf ("Image %s wrong type\n", aufile[idx]); return -1; } /* special case for prepare.img */ if (idx == IDX_PREPARE) return 0; /* recycle checksum */ checksum = image_get_data_size (hdr); /* for kernel and app the image header must also fit into flash */ if ((idx != IDX_DISK) && (idx != IDX_FIRMWARE)) checksum += image_get_header_size (); /* check the size does not exceed space in flash. HUSH scripts */ /* all have ausize[] set to 0 */ if ((ausize[idx] != 0) && (ausize[idx] < checksum)) { printf ("Image %s is bigger than FLASH\n", aufile[idx]); return -1; } /* check the time stamp from the EEPROM */ /* read it in */ i2c_read_multiple(0x54, auee_off[idx].time, 1, buf, sizeof(buf)); #ifdef CHECK_VALID_DEBUG printf ("buf[0] %#x buf[1] %#x buf[2] %#x buf[3] %#x " "as int %#x time %#x\n", buf[0], buf[1], buf[2], buf[3], *((unsigned int *)buf), image_get_time (hdr)); #endif /* check it */ if (*((unsigned int *)buf) >= image_get_time (hdr)) { printf ("Image %s is too old\n", aufile[idx]); return -1; } return 0; }