コード例 #1
0
static int imx_bbu_check_prereq(struct imx_internal_bbu_handler *imx_handler,
				const char *devicefile, struct bbu_data *data,
				enum filetype expected_type)
{
	int ret;
	const void *blob;
	size_t len;
	enum filetype type;

	type = file_detect_type(data->image, data->len);

	switch (type) {
	case filetype_arm_barebox:
		/*
		 * Specifying expected_type as unknown will disable the
		 * inner image type check.
		 *
		 * The only user of this code is
		 * imx_bbu_external_nor_register_handler() used by
		 * i.MX27.
		 */
		if (expected_type == filetype_unknown)
			break;

		blob = data->image + imx_handler->flash_header_offset;
		len  = data->len   - imx_handler->flash_header_offset;
		type = file_detect_type(blob, len);

		if (type != expected_type) {
			pr_err("Expected image type: %s, "
			       "detected image type: %s\n",
			       file_type_to_string(expected_type),
			       file_type_to_string(type));
			return -EINVAL;
		}
		break;
	default:
		if (!bbu_force(data, "Not an ARM barebox image"))
			return -EINVAL;
	}

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

	device_detect_by_name(devpath_to_name(devicefile));

	return 0;
}
コード例 #2
0
ファイル: tegra-bbu.c プロジェクト: zandar/barebox
static int tegra_bbu_emmc_handler(struct bbu_handler *handler,
                                  struct bbu_data *data)
{

    int fd, ret;

    if (file_detect_type(data->image + 0x4000, data->len) !=
            filetype_arm_barebox &&
            !bbu_force(data, "Not an ARM barebox image"))
        return -EINVAL;

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

    fd = open(data->devicefile, O_WRONLY);
    if (fd < 0)
        return fd;

    ret = write(fd, data->image, data->len);
    if (ret < 0) {
        pr_err("writing update to %s failed with %s\n",
               data->devicefile, strerror(-ret));
        goto err_close;
    }

    ret = 0;

err_close:
    close(fd);

    return ret;
}
コード例 #3
0
ファイル: bootm.c プロジェクト: AshishNamdev/barebox
static int do_bootz_linux_fdt(int fd, struct image_data *data)
{
	struct fdt_header __header, *header;
	void *oftree;
	int ret;

	u32 end;

	if (data->oftree)
		return -ENXIO;

	header = &__header;
	ret = read(fd, header, sizeof(*header));
	if (ret < sizeof(*header))
		return ret;

	if (file_detect_type(header, sizeof(*header)) != filetype_oftree)
		return -ENXIO;

	end = be32_to_cpu(header->totalsize);

	oftree = malloc(end + 0x8000);
	if (!oftree) {
		perror("zImage: oftree malloc");
		return -ENOMEM;
	}

	memcpy(oftree, header, sizeof(*header));

	end -= sizeof(*header);

	ret = read_full(fd, oftree + sizeof(*header), end);
	if (ret < 0)
		goto err_free;
	if (ret < end) {
		printf("premature end of image\n");
		ret = -EIO;
		goto err_free;
	}

	if (IS_BUILTIN(CONFIG_OFTREE)) {
		data->of_root_node = of_unflatten_dtb(NULL, oftree);
		if (!data->of_root_node) {
			pr_err("unable to unflatten devicetree\n");
			ret = -EINVAL;
			goto err_free;
		}
	} else {
		data->oftree = oftree;
	}

	pr_info("zImage: concatenated oftree detected\n");

	return 0;

err_free:
	free(oftree);

	return ret;
}
コード例 #4
0
/*
 * 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;
}
コード例 #5
0
ファイル: imx-bbu-internal.c プロジェクト: bmourit/barebox
static int imx_bbu_check_prereq(struct bbu_data *data)
{
	int ret;

	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;

	return 0;
}
コード例 #6
0
ファイル: filetype.c プロジェクト: Jokymon/barebox
enum filetype file_name_detect_type(const char *filename)
{
	int fd, ret;
	void *buf;
	enum filetype type = filetype_unknown;
	unsigned long bootsec;

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		return fd;

	buf = xzalloc(512);

	ret = read(fd, buf, 512);
	if (ret < 0)
		goto err_out;

	type = file_detect_type(buf);

	if (type == filetype_mbr) {
		/*
		 * Get the first partition start sector
		 * and check for FAT in it
		 */
		is_fat_or_mbr(buf, &bootsec);
		ret = lseek(fd, (bootsec) * 512, SEEK_SET);
		if (ret < 0)
			goto err_out;
		ret = read(fd, buf, 512);
		if (ret < 0)
			goto err_out;
		type = is_fat_or_mbr((u8 *)buf, NULL);
	}

err_out:
	close(fd);
	free(buf);

	return type;
}
コード例 #7
0
ファイル: filetype.c プロジェクト: cpdesign/barebox
enum filetype file_name_detect_type(const char *filename)
{
	int fd, ret;
	void *buf;
	enum filetype type = filetype_unknown;

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		return fd;

	buf = xmalloc(512);

	ret = read(fd, buf, 512);
	if (ret != 512)
		goto err_out;

	type = file_detect_type(buf);

err_out:
	close(fd);
	free(buf);

	return type;
}
コード例 #8
0
ファイル: uimage.c プロジェクト: centurysys/barebox
void *uimage_load_to_buf(struct uimage_handle *handle, int image_no,
		size_t *outsize)
{
	u32 size;
	int ret;
	struct uimage_handle_data *ihd;
	char ftbuf[128];
	enum filetype ft;
	void *buf;

	if (image_no >= handle->nb_data_entries)
		return NULL;

	ihd = &handle->ihd[image_no];

	ret = lseek(handle->fd, ihd->offset + handle->data_offset,
			SEEK_SET);
	if (ret < 0)
		return NULL;

	if (handle->header.ih_comp == IH_COMP_NONE) {
		buf = malloc(ihd->len);
		if (!buf)
			return NULL;

		ret = read_full(handle->fd, buf, ihd->len);
		if (ret < ihd->len) {
			free(buf);
			return NULL;
		}
		size = ihd->len;
		goto out;
	}

	ret = read(handle->fd, ftbuf, 128);
	if (ret < 0)
		return NULL;

	ft = file_detect_type(ftbuf, 128);
	if ((int)ft < 0)
		return NULL;

	if (ft != filetype_gzip)
		return NULL;

	ret = lseek(handle->fd, ihd->offset + handle->data_offset +
			ihd->len - 4,
			SEEK_SET);
	if (ret < 0)
		return NULL;

	ret = read(handle->fd, &size, 4);
	if (ret < 0)
		return NULL;

	size = le32_to_cpu(size);

	ret = lseek(handle->fd, ihd->offset + handle->data_offset,
			SEEK_SET);
	if (ret < 0)
		return NULL;

	buf = malloc(size);
	ret = uncompress_fd_to_buf(handle->fd, buf, uncompress_err_stdout);
	if (ret) {
		free(buf);
		return NULL;
	}

out:
	if (outsize)
		*outsize = size;

	return buf;
}
コード例 #9
0
ファイル: bootm.c プロジェクト: Jokymon/barebox
static int do_bootz_linux_fdt(int fd, struct image_data *data)
{
	struct fdt_header __header, *header;
	struct resource *r = data->os_res;
	struct resource *of_res = data->os_res;
	void *oftree;
	int ret;

	u32 end;

	header = &__header;
	ret = read(fd, header, sizeof(*header));
	if (ret < sizeof(*header))
		return ret;

	if (file_detect_type(header) != filetype_oftree)
		return -ENXIO;

	end = be32_to_cpu(header->totalsize);

	if (IS_BUILTIN(CONFIG_OFTREE)) {
		oftree = malloc(end + 0x8000);
		if (!oftree) {
			perror("zImage: oftree malloc");
			return -ENOMEM;
		}
	} else {

		of_res = request_sdram_region("oftree", r->start + resource_size(r), end);
		if (!of_res) {
			perror("zImage: oftree request_sdram_region");
			return -ENOMEM;
		}

		oftree = (void*)of_res->start;
	}

	memcpy(oftree, header, sizeof(*header));

	end -= sizeof(*header);

	ret = read_full(fd, oftree + sizeof(*header), end);
	if (ret < 0)
		return ret;
	if (ret < end) {
		printf("premature end of image\n");
		return -EIO;
	}

	if (IS_BUILTIN(CONFIG_OFTREE)) {
		fdt_open_into(oftree, oftree, end + 0x8000);

		ret = of_fix_tree(oftree);
		if (ret)
			return ret;

		data->oftree = oftree;
	}

	pr_info("zImage: concatenated oftree detected\n");

	return 0;
}
コード例 #10
0
ファイル: filer.cpp プロジェクト: samstyle/Xpeccy
int save_file(Computer* comp, const char* name, int id, int drv) {
	QString path = QDialog::trUtf8(name);
	QString flt;
	QString ext;
	xFileTypeInfo* inf = NULL;
	xFileTypeInfo* tin;
	xFileGroupInfo* grp;
	int i;
	int flg;
	if (id == FG_DISK)
		id = disk_id[drv & 3];
	if (id == FG_ALL)
		id = detect_hw_id(comp->hw->id);
	int err = ERR_OK;
	if (path.isEmpty()) {
		flt = file_get_hw_filter(comp, id, 1);
		if (flt.isEmpty()) {
			flt = file_get_group_filter(comp, id, 1);
			if (flt.isEmpty())
				flt = file_get_type_filter(id, 1);
		}
		if (!flt.isEmpty()) {
			filer->setWindowTitle("Save file");
			filer->setNameFilter(flt);
			filer->setAcceptMode(QFileDialog::AcceptSave);
			filer->setDirectory(conf.path.lastDir);
			filer->setHistory(QStringList());
			if (filer->exec()) {
				path = filer->selectedFiles().first();
				flt = filer->selectedNameFilter();
				grp = file_detect_grp(flt);
				if (grp->id != FL_NONE) {
					drv = grp->drv;
					i = 0;
					flg = 1;
					// scan group file types and check if path extension is the same
					while ((grp->child[i] != FL_NONE) && flg) {
						tin = file_find_type(grp->child[i]);
						if (tin) {
							if (path.endsWith(tin->ext, Qt::CaseInsensitive)) {
								flg = 0;
								inf = tin;
							}
						}
						i++;
					}
					// if no filetypes found, add default extension
					if (flg) {
						path.append(grp->defext);
					}
				} else {
					tin = file_detect_type(flt);
					if (tin->id != FL_NONE) {
						path.append(tin->ext);
					}
				}
			}
			strcpy(conf.path.lastDir, filer->directory().absolutePath().toLocal8Bit().data());
		}
	}
	if (path.isEmpty()) return err;
	if (drv < 0)
		drv = 0;
	if (!inf)
		inf = file_ext_type(path);
	if (inf) {
		if (inf->save) {
			err = inf->save(comp, path.toLocal8Bit().data(), drv);
		} else {
			shitHappens("Can't save that");
		}
	} else {
		shitHappens("Don't know such extension");
	}
	file_errors(err);
	return err;
}
コード例 #11
0
ファイル: imx-bbu-nand-fcb.c プロジェクト: gazoo74/barebox
static int imx_bbu_nand_update(struct bbu_handler *handler, struct bbu_data *data)
{
	struct imx_nand_fcb_bbu_handler *imx_handler =
		container_of(handler, struct imx_nand_fcb_bbu_handler, handler);
	struct cdev *bcb_cdev;
	struct mtd_info *mtd;
	int ret, i;
	struct fcb_block *fcb = NULL;
	void *fw = NULL, *fw_orig = NULL;
	unsigned fw_size, partition_size;
	enum filetype filetype;
	unsigned num_blocks_fw;
	int pages_per_block;
	int used = 0;
	int fw_orig_len;
	int used_refresh = 0, unused_refresh = 0;

	if (data->image) {
		filetype = file_detect_type(data->image, data->len);

		if (filetype != imx_handler->filetype &&
			!bbu_force(data, "Image is not of type %s but of type %s",
				file_type_to_string(imx_handler->filetype),
				file_type_to_string(filetype)))
			return -EINVAL;
	}

	bcb_cdev = cdev_by_name(handler->devicefile);
	if (!bcb_cdev) {
		pr_err("%s: No FCB device!\n", __func__);
		return -ENODEV;
	}

	mtd = bcb_cdev->mtd;
	partition_size = mtd->size;
	pages_per_block = mtd->erasesize / mtd->writesize;

	for (i = 0; i < 4; i++) {
		read_fcb(mtd, i, &fcb);
		if (fcb)
			break;
	}

	/*
	 * This code uses the following layout in the Nand flash:
	 *
	 * fwmaxsize = (n_blocks - 4) / 2
	 *
	 * block
	 *
	 * 0              ----------------------
	 *                | FCB/DBBT 0         |
	 * 1              ----------------------
	 *                | FCB/DBBT 1         |
	 * 2              ----------------------
	 *                | FCB/DBBT 2         |
	 * 3              ----------------------
	 *                | FCB/DBBT 3         |
	 * 4              ----------------------
	 *                | Firmware slot 0    |
	 * 4 + fwmaxsize  ----------------------
	 *                | Firmware slot 1    |
	 *                ----------------------
	 *
	 * We want a robust update in which a power failure may occur
	 * everytime without bricking the board, so here's the strategy:
	 *
	 * The FCBs contain pointers to the firmware slots in the
	 * Firmware1_startingPage and Firmware2_startingPage fields. Note that
	 * Firmware1_startingPage doesn't necessarily point to slot 0. We
	 * exchange the pointers during update to atomically switch between the
	 * old and the new firmware.
	 *
	 * - We read the first valid FCB and the firmware slots.
	 * - We check which firmware slot is currently used by the ROM:
	 *    - if no FCB is found or its layout differs from the above layout,
	 *      continue without robust update
	 *   - if only one firmware slot is readable, the ROM uses it
	 *   - if both slots are readable, the ROM will use slot 0
	 * - Step 1: erase/update the slot currently unused by the ROM
	 * - Step 2: Update FCBs/DBBTs, thereby letting Firmware1_startingPage
	 *           point to the slot we just updated. From this moment
	 *           on the new firmware will be used and running a
	 *           refresh/repair after a power failure after this
	 *           step will complete the update.
	 * - Step 3: erase/update the other firmwre slot
	 * - Step 4: Eventually write FCBs/DBBTs again. This may become
	 *           necessary when step 3 revealed new bad blocks.
	 *
	 * This robust update only works when the original FCBs on the device
	 * uses the same layout as this code does. In other cases update will
	 * also work, but it won't be robust against power failures.
	 *
	 * Refreshing the firmware which is needed when blocks become unreadable
	 * due to read disturbance works the same way, only that the new firmware
	 * is the same as the old firmware and that it will only be written when
	 * reading from the device returns -EUCLEAN indicating that a block needs
	 * to be rewritten.
	 */
	if (fcb)
		read_firmware_all(mtd, fcb, &fw_orig, &fw_orig_len,
				  &used_refresh, &unused_refresh, &used);

	if (data->image) {
		/*
		 * We have to write one additional page to make the ROM happy.
		 * Maybe the PagesInFirmwarex fields are really the number of pages - 1.
		 * kobs-ng has the same.
		 */
		fw_size = ALIGN(data->len + mtd->writesize, mtd->writesize);
		fw = xzalloc(fw_size);
		memcpy(fw, data->image, data->len);
		free(fw_orig);
		used_refresh = 1;
		unused_refresh = 1;

		free(fcb);
		fcb = xzalloc(sizeof(*fcb));
		fcb->Firmware1_startingPage = imx_bbu_firmware_start_block(mtd, !used) * pages_per_block;
		fcb->Firmware2_startingPage = imx_bbu_firmware_start_block(mtd, used) * pages_per_block;
		fcb->PagesInFirmware1 = fw_size / mtd->writesize;
		fcb->PagesInFirmware2 = fcb->PagesInFirmware1;

		fcb_create(imx_handler, fcb, mtd);
	} else {
		if (!fcb) {
			pr_err("No FCB found on device, cannot refresh\n");
			ret = -EINVAL;
			goto out;
		}

		if (!fw_orig) {
			pr_err("No firmware found on device, cannot refresh\n");
			ret = -EINVAL;
			goto out;
		}

		fw = fw_orig;
		fw_size = fw_orig_len;
		pr_info("Refreshing existing firmware\n");
	}

	num_blocks_fw = imx_bbu_firmware_max_blocks(mtd);

	if (num_blocks_fw * mtd->erasesize < fw_size) {
		pr_err("Not enough space for update\n");
		return -ENOSPC;
	}

	ret = bbu_confirm(data);
	if (ret)
		goto out;

	/* Step 1: write firmware which is currently unused by the ROM */
	if (unused_refresh) {
		pr_info("%sing slot %d\n", data->image ? "updat" : "refresh", !used);
		ret = imx_bbu_write_firmware(mtd, !used, fw, fw_size);
		if (ret < 0)
			goto out;
	} else {
		pr_info("firmware slot %d still ok, nothing to do\n", !used);
	}

	/*
	 * Step 2: Write FCBs/DBBTs. This will use the firmware we have
	 * just written as primary firmware. From now on the new
	 * firmware will be booted.
	 */
	ret = imx_bbu_write_fcbs_dbbts(mtd, fcb);
	if (ret < 0)
		goto out;

	/* Step 3: Write the secondary firmware */
	if (used_refresh) {
		pr_info("%sing slot %d\n", data->image ? "updat" : "refresh", used);
		ret = imx_bbu_write_firmware(mtd, used, fw, fw_size);
		if (ret < 0)
			goto out;
	} else {
		pr_info("firmware slot %d still ok, nothing to do\n", used);
	}

	/*
	 * Step 4: If writing the secondary firmware discovered new bad
	 * blocks, write the FCBs/DBBTs again with updated bad block
	 * information.
	 */
	if (ret > 0) {
		pr_info("New bad blocks detected, writing FCBs/DBBTs again\n");
		ret = imx_bbu_write_fcbs_dbbts(mtd, fcb);
		if (ret < 0)
			goto out;
	}

out:
	free(fw);
	free(fcb);

	return ret;
}
コード例 #12
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);
	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;
}