static int image_create_payload(void *payload_start, size_t payloadsz, const char *payload_filename) { FILE *payload; uint32_t *payload_checksum = (uint32_t *) (payload_start + payloadsz); int ret; payload = fopen(payload_filename, "r"); if (!payload) { fprintf(stderr, "Cannot open payload file %s\n", payload_filename); return -1; } ret = fread(payload_start, payloadsz, 1, payload); if (ret != 1) { fprintf(stderr, "Cannot read payload file %s\n", payload_filename); return -1; } fclose(payload); *payload_checksum = image_checksum32(payload_start, payloadsz); return 0; }
static void kwbimage_set_header(void *ptr, struct stat *sbuf, int ifd, struct image_tool_params *params) { FILE *fcfg; void *image = NULL; int version; size_t headersz = 0; uint32_t checksum; int ret; int size; fcfg = fopen(params->imagename, "r"); if (!fcfg) { fprintf(stderr, "Could not open input file %s\n", params->imagename); exit(EXIT_FAILURE); } image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element)); if (!image_cfg) { fprintf(stderr, "Cannot allocate memory\n"); fclose(fcfg); exit(EXIT_FAILURE); } memset(image_cfg, 0, IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element)); rewind(fcfg); ret = image_create_config_parse(fcfg); fclose(fcfg); if (ret) { free(image_cfg); exit(EXIT_FAILURE); } /* The MVEBU BootROM does not allow non word aligned payloads */ sbuf->st_size = ALIGN_SUP(sbuf->st_size, 4); version = image_get_version(); switch (version) { /* * Fallback to version 0 if no version is provided in the * cfg file */ case -1: case 0: image = image_create_v0(&headersz, params, sbuf->st_size); break; case 1: image = image_create_v1(&headersz, params, sbuf->st_size); break; default: fprintf(stderr, "Unsupported version %d\n", version); free(image_cfg); exit(EXIT_FAILURE); } if (!image) { fprintf(stderr, "Could not create image\n"); free(image_cfg); exit(EXIT_FAILURE); } free(image_cfg); /* Build and add image checksum header */ checksum = cpu_to_le32(image_checksum32((uint32_t *)ptr, sbuf->st_size)); size = write(ifd, &checksum, sizeof(uint32_t)); if (size != sizeof(uint32_t)) { fprintf(stderr, "Error:%s - Checksum write %d bytes %s\n", params->cmdname, size, params->imagefile); exit(EXIT_FAILURE); } sbuf->st_size += sizeof(uint32_t); /* Finally copy the header into the image area */ memcpy(ptr, image, headersz); free(image); }
static int image_extract_v0(void *fdimap, const char *output, FILE *focfg) { struct main_hdr_v0 *main_hdr = fdimap; struct ext_hdr_v0 *ext_hdr; const char *boot_mode_name; uint32_t *img_checksum; size_t payloadsz; int cksum, i; /* * Verify checksum. When calculating the header, discard the * last byte of the header, which itself contains the * checksum. */ cksum = image_checksum8(main_hdr, sizeof(struct main_hdr_v0)-1); if (cksum != main_hdr->checksum) { fprintf(stderr, "Invalid main header checksum: 0x%08x vs. 0x%08x\n", cksum, main_hdr->checksum); return -1; } boot_mode_name = image_boot_mode_name(main_hdr->blockid); if (!boot_mode_name) { fprintf(stderr, "Invalid boot ID: 0x%x\n", main_hdr->blockid); return -1; } fprintf(focfg, "VERSION 0\n"); fprintf(focfg, "BOOT_FROM %s\n", boot_mode_name); fprintf(focfg, "DESTADDR %08x\n", main_hdr->destaddr); fprintf(focfg, "EXECADDR %08x\n", main_hdr->execaddr); if (!strcmp(boot_mode_name, "nand")) { const char *nand_ecc_mode = image_nand_ecc_mode_name(main_hdr->nandeccmode); fprintf(focfg, "NAND_ECCMODE %s\n", nand_ecc_mode); fprintf(focfg, "NAND_PAGESZ %08x\n", main_hdr->nandpagesize); } /* No extension header, we're done */ if (!main_hdr->ext) return 0; ext_hdr = fdimap + sizeof(struct main_hdr_v0); for (i = 0; i < EXT_HDR_V0_REG_COUNT; i++) { if (ext_hdr->rcfg[i].raddr == 0 && ext_hdr->rcfg[i].rdata == 0) break; fprintf(focfg, "DATA %08x %08x\n", ext_hdr->rcfg[i].raddr, ext_hdr->rcfg[i].rdata); } /* The image is concatenated with a 32 bits checksum */ payloadsz = main_hdr->blocksize - sizeof(uint32_t); img_checksum = (uint32_t *) (fdimap + main_hdr->srcaddr + payloadsz); if (*img_checksum != image_checksum32(fdimap + main_hdr->srcaddr, payloadsz)) { fprintf(stderr, "The image checksum does not match\n"); return -1; } /* Finally, handle the image itself */ fprintf(focfg, "PAYLOAD %s/payload\n", output); return image_extract_payload(fdimap + main_hdr->srcaddr, payloadsz, output); }