/* * 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; }