예제 #1
0
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;
}
예제 #2
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);
}
예제 #3
0
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;
}
예제 #4
0
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;
}