Esempio n. 1
0
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);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}