static size_t image_headersz_v1(struct image_tool_params *params, int *hasext) { struct image_cfg_element *binarye; size_t headersz; int ret; /* * Calculate the size of the header and the size of the * payload */ headersz = sizeof(struct main_hdr_v1); if (image_count_options(IMAGE_CFG_BINARY) > 1) { fprintf(stderr, "More than one binary blob, not supported\n"); return 0; } if (image_count_options(IMAGE_CFG_PAYLOAD) > 1) { fprintf(stderr, "More than one payload, not possible\n"); return 0; } binarye = image_find_option(IMAGE_CFG_BINARY); if (binarye) { struct stat s; ret = stat(binarye->binary.file, &s); if (ret < 0) { char cwd[PATH_MAX]; char *dir = cwd; memset(cwd, 0, sizeof(cwd)); if (!getcwd(cwd, sizeof(cwd))) { dir = "current working directory"; perror("getcwd() failed"); } fprintf(stderr, "Didn't find the file '%s' in '%s' which is mandatory to generate the image\n" "This file generally contains the DDR3 training code, and should be extracted from an existing bootable\n" "image for your board. See 'kwbimage -x' to extract it from an existing image.\n", binarye->binary.file, dir); return 0; } headersz += s.st_size + binarye->binary.nargs * sizeof(unsigned int); if (hasext) *hasext = 1; } /* * The payload should be aligned on some reasonable * boundary */ return ALIGN_SUP(headersz, 4096); }
static void *image_create_v0(size_t *imagesz, struct image_tool_params *params, int payloadsz) { struct image_cfg_element *e; size_t headersz; struct main_hdr_v0 *main_hdr; struct ext_hdr_v0 *ext_hdr; void *image; int has_ext = 0; /* * Calculate the size of the header and the size of the * payload */ headersz = sizeof(struct main_hdr_v0); if (image_count_options(IMAGE_CFG_DATA) > 0) { has_ext = 1; headersz += sizeof(struct ext_hdr_v0); } if (image_count_options(IMAGE_CFG_PAYLOAD) > 1) { fprintf(stderr, "More than one payload, not possible\n"); return NULL; } image = malloc(headersz); if (!image) { fprintf(stderr, "Cannot allocate memory for image\n"); return NULL; } memset(image, 0, headersz); main_hdr = image; /* Fill in the main header */ main_hdr->blocksize = cpu_to_le32(payloadsz + sizeof(uint32_t) - headersz); main_hdr->srcaddr = cpu_to_le32(headersz); main_hdr->ext = has_ext; main_hdr->destaddr = cpu_to_le32(params->addr); main_hdr->execaddr = cpu_to_le32(params->ep); e = image_find_option(IMAGE_CFG_BOOT_FROM); if (e) main_hdr->blockid = e->bootfrom; e = image_find_option(IMAGE_CFG_NAND_ECC_MODE); if (e) main_hdr->nandeccmode = e->nandeccmode; e = image_find_option(IMAGE_CFG_NAND_PAGESZ); if (e) main_hdr->nandpagesize = cpu_to_le16(e->nandpagesz); main_hdr->checksum = image_checksum8(image, sizeof(struct main_hdr_v0)); /* Generate the ext header */ if (has_ext) { int cfgi, datai; ext_hdr = image + sizeof(struct main_hdr_v0); ext_hdr->offset = cpu_to_le32(0x40); for (cfgi = 0, datai = 0; cfgi < cfgn; cfgi++) { e = &image_cfg[cfgi]; if (e->type != IMAGE_CFG_DATA) continue; ext_hdr->rcfg[datai].raddr = cpu_to_le32(e->regdata.raddr); ext_hdr->rcfg[datai].rdata = cpu_to_le32(e->regdata.rdata); datai++; } ext_hdr->checksum = image_checksum8(ext_hdr, sizeof(struct ext_hdr_v0)); } *imagesz = headersz; return image; }
static void *image_create_v1(struct image_cfg_element *image_cfg, int cfgn, const char *output, size_t *imagesz) { struct image_cfg_element *e, *payloade, *binarye; struct main_hdr_v1 *main_hdr; size_t headersz, payloadsz, totalsz; void *image, *cur; int hasext = 0; int ret; /* Calculate the size of the header and the size of the * payload */ headersz = sizeof(struct main_hdr_v1); payloadsz = 0; if (image_count_options(image_cfg, cfgn, IMAGE_CFG_BINARY) > 1) { fprintf(stderr, "More than one binary blob, not supported\n"); return NULL; } if (image_count_options(image_cfg, cfgn, IMAGE_CFG_PAYLOAD) > 1) { fprintf(stderr, "More than one payload, not possible\n"); return NULL; } binarye = image_find_option(image_cfg, cfgn, IMAGE_CFG_BINARY); if (binarye) { struct stat s; ret = stat(binarye->binary.file, &s); if (ret < 0) { char *cwd = get_current_dir_name(); fprintf(stderr, "Didn't find the file '%s' in '%s' which is mandatory to generate the image\n" "This file generally contains the DDR3 training code, and should be extracted from an existing bootable\n" "image for your board. See 'kwbimage -x' to extract it from an existing image.\n", binarye->binary.file, cwd); free(cwd); return NULL; } headersz += s.st_size + binarye->binary.nargs * sizeof(unsigned int); hasext = 1; } payloade = image_find_option(image_cfg, cfgn, IMAGE_CFG_PAYLOAD); if (payloade) { struct stat s; ret = stat(payloade->payload, &s); if (ret < 0) { fprintf(stderr, "Cannot stat payload file %s\n", payloade->payload); return NULL; } payloadsz = s.st_size; } /* The payload should be aligned on some reasonable * boundary */ headersz = ALIGN_SUP(headersz, 4096); /* The total size includes the headers, the payload, and the * 32 bits checksum at the end of the payload */ totalsz = headersz + payloadsz + sizeof(uint32_t); image = malloc(totalsz); if (!image) { fprintf(stderr, "Cannot allocate memory for image\n"); return NULL; } memset(image, 0, totalsz); cur = main_hdr = image; cur += sizeof(struct main_hdr_v1); /* Fill the main header */ main_hdr->blocksize = payloadsz + sizeof(uint32_t); main_hdr->headersz_lsb = headersz & 0xFFFF; main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16; main_hdr->srcaddr = headersz; main_hdr->ext = hasext; main_hdr->version = 1; e = image_find_option(image_cfg, cfgn, IMAGE_CFG_BOOT_FROM); if (e) main_hdr->blockid = e->bootfrom; e = image_find_option(image_cfg, cfgn, IMAGE_CFG_DEST_ADDR); if (e) main_hdr->destaddr = e->dstaddr; e = image_find_option(image_cfg, cfgn, IMAGE_CFG_EXEC_ADDR); if (e) main_hdr->execaddr = e->execaddr; e = image_find_option(image_cfg, cfgn, IMAGE_CFG_NAND_BLKSZ); if (e) main_hdr->nandblocksize = e->nandblksz / (64 * 1024); e = image_find_option(image_cfg, cfgn, IMAGE_CFG_NAND_BADBLK_LOCATION); if (e) main_hdr->nandbadblklocation = e->nandbadblklocation; if (binarye) { struct opt_hdr_v1 *hdr = cur; unsigned int *args; size_t binhdrsz; struct stat s; int argi; FILE *bin; hdr->headertype = OPT_HDR_V1_BINARY_TYPE; bin = fopen(binarye->binary.file, "r"); if (!bin) { fprintf(stderr, "Cannot open binary file %s\n", binarye->binary.file); return NULL; } fstat(fileno(bin), &s); binhdrsz = sizeof(struct opt_hdr_v1) + (binarye->binary.nargs + 1) * sizeof(unsigned int) + s.st_size; hdr->headersz_lsb = binhdrsz & 0xFFFF; hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16; cur += sizeof(struct opt_hdr_v1); args = cur; *args = binarye->binary.nargs; args++; for (argi = 0; argi < binarye->binary.nargs; argi++) args[argi] = binarye->binary.args[argi]; cur += (binarye->binary.nargs + 1) * sizeof(unsigned int); ret = fread(cur, s.st_size, 1, bin); if (ret != 1) { fprintf(stderr, "Could not read binary image %s\n", binarye->binary.file); return NULL; } fclose(bin); cur += s.st_size; /* * For now, we don't support more than one binary * header, and no other header types are * supported. So, the binary header is necessarily the * last one */ *((unsigned char *) cur) = 0; cur += sizeof(uint32_t); } /* Calculate and set the header checksum */ main_hdr->checksum = image_checksum8(main_hdr, headersz); if (payloade) { ret = image_create_payload(image + headersz, payloadsz, payloade->payload); if (ret < 0) return NULL; } *imagesz = totalsz; return image; }
static void *image_create_v0(struct image_cfg_element *image_cfg, int cfgn, const char *output, size_t *imagesz) { struct image_cfg_element *e, *payloade; size_t headersz, payloadsz, totalsz; struct main_hdr_v0 *main_hdr; struct ext_hdr_v0 *ext_hdr; void *image; int has_ext = 0; int ret; /* Calculate the size of the header and the size of the * payload */ headersz = sizeof(struct main_hdr_v0); payloadsz = 0; if (image_count_options(image_cfg, cfgn, IMAGE_CFG_DATA) > 0) { has_ext = 1; headersz += sizeof(struct ext_hdr_v0); } if (image_count_options(image_cfg, cfgn, IMAGE_CFG_PAYLOAD) > 1) { fprintf(stderr, "More than one payload, not possible\n"); return NULL; } payloade = image_find_option(image_cfg, cfgn, IMAGE_CFG_PAYLOAD); if (payloade) { struct stat s; int ret; ret = stat(payloade->payload, &s); if (ret < 0) { fprintf(stderr, "Cannot stat payload file %s\n", payloade->payload); return NULL; } payloadsz = s.st_size; } /* Headers, payload and 32-bits checksum */ totalsz = headersz + payloadsz + sizeof(uint32_t); image = malloc(totalsz); if (!image) { fprintf(stderr, "Cannot allocate memory for image\n"); return NULL; } memset(image, 0, totalsz); main_hdr = image; /* Fill in the main header */ main_hdr->blocksize = payloadsz + sizeof(uint32_t); main_hdr->srcaddr = headersz; main_hdr->ext = has_ext; e = image_find_option(image_cfg, cfgn, IMAGE_CFG_BOOT_FROM); if (e) main_hdr->blockid = e->bootfrom; e = image_find_option(image_cfg, cfgn, IMAGE_CFG_DEST_ADDR); if (e) main_hdr->destaddr = e->dstaddr; e = image_find_option(image_cfg, cfgn, IMAGE_CFG_EXEC_ADDR); if (e) main_hdr->execaddr = e->execaddr; e = image_find_option(image_cfg, cfgn, IMAGE_CFG_NAND_ECC_MODE); if (e) main_hdr->nandeccmode = e->nandeccmode; e = image_find_option(image_cfg, cfgn, IMAGE_CFG_NAND_PAGESZ); if (e) main_hdr->nandpagesize = e->nandpagesz; main_hdr->checksum = image_checksum8(image, sizeof(struct main_hdr_v0)); /* Generate the ext header */ if (has_ext) { int cfgi, datai; ext_hdr = image + sizeof(struct main_hdr_v0); ext_hdr->offset = 0x40; for (cfgi = 0, datai = 0; cfgi < cfgn; cfgi++) { e = &image_cfg[cfgi]; if (e->type != IMAGE_CFG_DATA) continue; ext_hdr->rcfg[datai].raddr = e->regdata.raddr; ext_hdr->rcfg[datai].rdata = e->regdata.rdata; datai++; } ext_hdr->checksum = image_checksum8(ext_hdr, sizeof(struct ext_hdr_v0)); } if (payloade) { ret = image_create_payload(image + headersz, payloadsz, payloade->payload); if (ret < 0) return NULL; } *imagesz = totalsz; return image; }