/* * Update barebox on a v1 type internal boot (i.MX25, i.MX35, i.MX51) * * This constructs a DCD header, adds the specific DCD data and writes * the resulting image to the device. Currently this handles MMC/SD * devices. */ static int imx_bbu_internal_v1_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 *flash_header; unsigned long flash_header_offset = imx_handler->flash_header_offset; u32 *dcd_image_size; void *imx_pre_image; int imx_pre_image_size = 0x2000; 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); imx_pre_image = xzalloc(imx_pre_image_size); flash_header = imx_pre_image + flash_header_offset; flash_header->app_code_jump_vector = imx_handler->app_dest + 0x1000; flash_header->app_code_barker = APP_CODE_BARKER; flash_header->app_code_csf = 0; flash_header->dcd_ptr_ptr = imx_handler->app_dest + flash_header_offset + offsetof(struct imx_flash_header, dcd); flash_header->super_root_key = 0; flash_header->dcd = imx_handler->app_dest + flash_header_offset + offsetof(struct imx_flash_header, dcd_barker); flash_header->app_dest = imx_handler->app_dest; flash_header->dcd_barker = DCD_BARKER; flash_header->dcd_block_len = imx_handler->dcdsize; memcpy((void *)flash_header + sizeof(*flash_header), imx_handler->dcd, imx_handler->dcdsize); dcd_image_size = (imx_pre_image + flash_header_offset + sizeof(*flash_header) + imx_handler->dcdsize); *dcd_image_size = ALIGN(imx_pre_image_size + data->len, 4096); /* 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); ret = imx_bbu_write_device(imx_handler, data, buf, image_len); 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); 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; }
static int __imx_bbu_write_device(struct imx_internal_bbu_handler *imx_handler, struct bbu_data *data) { return imx_bbu_write_device(imx_handler, data->devicefile, data, data->image, data->len); }
/* * 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; }