Beispiel #1
0
/*
 * Update barebox on a v2 type internal boot (i.MX53)
 *
 * This constructs a DCD header, adds the specific DCD data and writes
 * the resulting image to the device. Currently this handles MMC/SD
 * and NAND devices.
 */
static int imx_bbu_internal_v2_update(struct bbu_handler *handler, struct bbu_data *data)
{
	struct imx_internal_bbu_handler *imx_handler =
		container_of(handler, struct imx_internal_bbu_handler, handler);
	void *imx_pre_image = NULL;
	int imx_pre_image_size;
	int ret, image_len;
	void *buf;

	ret = imx_bbu_check_prereq(data);
	if (ret)
		return ret;

	if (imx_handler->dcd) {
		imx_pre_image_size = 0x2000;
	} else {
		uint32_t *barker = data->image + imx_handler->flash_header_offset;

		if (*barker != IVT_BARKER) {
			printf("Board does not provide DCD data and this image is no imximage\n");
			return -EINVAL;
		}

		imx_pre_image_size = 0;
	}

	if (imx_handler->flags & IMX_INTERNAL_FLAG_NAND)
		/* NAND needs additional space for the DBBT */
		imx_pre_image_size += 0x6000;

	if (imx_pre_image_size)
		imx_pre_image = xzalloc(imx_pre_image_size);

	if (imx_handler->dcd)
		imx_bbu_internal_v2_init_flash_header(handler, data, imx_pre_image, imx_pre_image_size);

	/* Create a buffer containing header and image data */
	image_len = data->len + imx_pre_image_size;
	buf = xzalloc(image_len);
	if (imx_pre_image_size)
		memcpy(buf, imx_pre_image, imx_pre_image_size);
	memcpy(buf + imx_pre_image_size, data->image, data->len);

	if (imx_handler->flags & IMX_INTERNAL_FLAG_NAND) {
		ret = imx_bbu_internal_v2_write_nand_dbbt(imx_handler, data, buf,
				image_len);
		goto out_free_buf;
	}

	ret = imx_bbu_write_device(imx_handler, data, buf, image_len);

out_free_buf:
	free(buf);

	free(imx_pre_image);
	return ret;
}
/*
 * Update barebox on a v2 type internal boot (i.MX53)
 *
 * This constructs a DCD header, adds the specific DCD data and writes
 * the resulting image to the device. Currently this handles MMC/SD
 * and NAND devices.
 */
static int imx_bbu_internal_v2_update(struct bbu_handler *handler, struct bbu_data *data)
{
	struct imx_internal_bbu_handler *imx_handler =
		container_of(handler, struct imx_internal_bbu_handler, handler);
	struct imx_flash_header_v2 *flash_header;
	unsigned long flash_header_offset = imx_handler->flash_header_offset;
	void *imx_pre_image;
	int imx_pre_image_size;
	int ret, image_len;
	void *buf;

	if (file_detect_type(data->image, data->len) != filetype_arm_barebox) {
		if (!bbu_force(data, "Not an ARM barebox image"))
			return -EINVAL;
	}

	ret = bbu_confirm(data);
	if (ret)
		return ret;

	printf("updating to %s\n", data->devicefile);

	if (imx_handler->flags & IMX_INTERNAL_FLAG_NAND)
		/* NAND needs additional space for the DBBT */
		imx_pre_image_size = 0x8000;
	else
		imx_pre_image_size = 0x2000;

	imx_pre_image = xzalloc(imx_pre_image_size);
	flash_header = imx_pre_image + flash_header_offset;

	flash_header->header.tag = IVT_HEADER_TAG;
	flash_header->header.length = cpu_to_be16(32);
	flash_header->header.version = IVT_VERSION;

	flash_header->entry = imx_handler->app_dest + imx_pre_image_size;
	if (imx_handler->dcdsize)
		flash_header->dcd_ptr = imx_handler->app_dest + flash_header_offset +
			offsetof(struct imx_flash_header_v2, dcd);
	flash_header->boot_data_ptr = imx_handler->app_dest +
		flash_header_offset + offsetof(struct imx_flash_header_v2, boot_data);
	flash_header->self = imx_handler->app_dest + flash_header_offset;

	flash_header->boot_data.start = imx_handler->app_dest;
	flash_header->boot_data.size = ALIGN(imx_pre_image_size + data->len, 4096);;

	if (imx_handler->dcdsize) {
		flash_header->dcd.header.tag = DCD_HEADER_TAG;
		flash_header->dcd.header.length = cpu_to_be16(sizeof(struct imx_dcd) +
				imx_handler->dcdsize);
		flash_header->dcd.header.version = DCD_VERSION;
	}

	/* Add dcd data */
	memcpy((void *)flash_header + sizeof(*flash_header), imx_handler->dcd, imx_handler->dcdsize);

	/* Create a buffer containing header and image data */
	image_len = data->len + imx_pre_image_size;
	buf = xzalloc(image_len);
	memcpy(buf, imx_pre_image, imx_pre_image_size);
	memcpy(buf + imx_pre_image_size, data->image, data->len);

	if (imx_handler->flags & IMX_INTERNAL_FLAG_NAND) {
		ret = imx_bbu_internal_v2_write_nand_dbbt(imx_handler, data, buf,
				image_len);
		goto out_free_buf;
	}

	ret = imx_bbu_write_device(imx_handler, data, buf, image_len);

out_free_buf:
	free(buf);

	free(imx_pre_image);
	return ret;
}