示例#1
0
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;
}
示例#2
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);
}
示例#3
0
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);
}