static int kwbimage_verify_header(unsigned char *ptr, int image_size, struct image_tool_params *params) { struct main_hdr_v0 *main_hdr; struct ext_hdr_v0 *ext_hdr; uint8_t checksum; main_hdr = (void *)ptr; checksum = image_checksum8(ptr, sizeof(struct main_hdr_v0) - sizeof(uint8_t)); if (checksum != main_hdr->checksum) return -FDT_ERR_BADSTRUCTURE; /* Only version 0 extended header has checksum */ if (image_version((void *)ptr) == 0) { ext_hdr = (void *)ptr + sizeof(struct main_hdr_v0); checksum = image_checksum8(ext_hdr, sizeof(struct ext_hdr_v0) - sizeof(uint8_t)); if (checksum != ext_hdr->checksum) return -FDT_ERR_BADSTRUCTURE; } return 0; }
static void kwbimage_print_header(const void *ptr) { struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr; printf("Image Type: MVEBU Boot from %s Image\n", image_boot_mode_name(mhdr->blockid)); printf("Image version:%d\n", image_version((void *)ptr)); printf("Data Size: "); genimg_print_size(mhdr->blocksize - sizeof(uint32_t)); printf("Load Address: %08x\n", mhdr->destaddr); printf("Entry Point: %08x\n", mhdr->execaddr); }
static int kwboot_img_patch_hdr(void *img, size_t size) { int rc; struct main_hdr_v1 *hdr; uint8_t csum; size_t hdrsz = sizeof(*hdr); int image_ver; rc = -1; hdr = img; if (size < hdrsz) { errno = EINVAL; goto out; } image_ver = image_version(img); if (image_ver < 0) { fprintf(stderr, "Invalid image header version\n"); errno = EINVAL; goto out; } if (image_ver == 0) hdrsz = sizeof(*hdr); else hdrsz = KWBHEADER_V1_SIZE(hdr); csum = kwboot_img_csum8(hdr, hdrsz) - hdr->checksum; if (csum != hdr->checksum) { errno = EINVAL; goto out; } if (hdr->blockid == IBR_HDR_UART_ID) { rc = 0; goto out; } hdr->blockid = IBR_HDR_UART_ID; /* * Subtract mkimage header size from destination address * as this header is not expected by the Marvell BootROM. * This way, the execution address is identical to the * one the image is compiled for (TEXT_BASE). */ hdr->destaddr = hdr->destaddr - sizeof(struct image_header); if (image_ver == 0) { struct main_hdr_v0 *hdr_v0 = img; hdr_v0->nandeccmode = IBR_HDR_ECC_DISABLED; hdr_v0->nandpagesize = 0; hdr_v0->srcaddr = hdr_v0->ext ? sizeof(struct kwb_header) : sizeof(*hdr_v0); } hdr->checksum = kwboot_img_csum8(hdr, hdrsz) - csum; rc = 0; out: return rc; }
static int image_extract(const char *input, const char *output) { int fdi, ret; struct stat fdistat, fdostat; void *fdimap; char *focfgname; FILE *focfg; fdi = open(input, O_RDONLY); if (fdi < 0) { fprintf(stderr, "Cannot open input file %s: %m\n", input); return -1; } ret = fstat(fdi, &fdistat); if (ret < 0) { fprintf(stderr, "Cannot stat input file %s: %m\n", input); close(fdi); return -1; } fdimap = mmap(NULL, fdistat.st_size, PROT_READ, MAP_PRIVATE, fdi, 0); if (fdimap == MAP_FAILED) { fprintf(stderr, "Cannot map input file %s: %m\n", input); close(fdi); return -1; } close(fdi); ret = stat(output, &fdostat); if (ret < 0) { fprintf(stderr, "Cannot stat output directory %s: %m\n", output); munmap(fdimap, fdistat.st_size); return -1; } if (!S_ISDIR(fdostat.st_mode)) { fprintf(stderr, "Output %s should be a directory\n", output); munmap(fdimap, fdistat.st_size); return -1; } ret = asprintf(&focfgname, "%s/kwbimage.cfg", output); if (ret < 0) { fprintf(stderr, "Failed to allocate memory\n"); munmap(fdimap, fdistat.st_size); return -1; } focfg = fopen(focfgname, "w+"); if (!focfg) { fprintf(stderr, "Output file %s could not be created\n", focfgname); free(focfgname); munmap(fdimap, fdistat.st_size); return -1; } free(focfgname); if (image_version(fdimap) == 0) ret = image_extract_v0(fdimap, output, focfg); else if (image_version(fdimap) == 1) ret = image_extract_v1(fdimap, output, focfg); else { fprintf(stderr, "Invalid image version %d\n", image_version(fdimap)); ret = -1; } fclose(focfg); munmap(fdimap, fdistat.st_size); return ret; }