diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2018-01-10 14:20:57 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2018-01-11 08:32:41 +0100 |
commit | 91e08222389da159944d918bbe6eee7510da8872 (patch) | |
tree | 570c5a01a24cf8cd2ef0932cff521074a1f95a12 /common | |
parent | e0e4c722c98737a4202b9fabc60bff6d2c6050f4 (diff) | |
download | barebox-91e08222389da159944d918bbe6eee7510da8872.tar.gz barebox-91e08222389da159944d918bbe6eee7510da8872.tar.xz |
ubiformat: Add ubiformat write function
The ubiformat C API expects an image file as argument. With upcoming
Android fastboot sparse image support we can no longer provide a
complete image anymore. With this patch we can write an image in
multiple chunks after we've formatted a MTD device with ubiformat.
ubiformat_write will skip the EC header in both the MTD device we
write to and also the image we read from, so we can flash an image
on a MTD device containing EC headers already.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'common')
-rw-r--r-- | common/ubiformat.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/common/ubiformat.c b/common/ubiformat.c index aaa1f5d6bc..4c5f1f5794 100644 --- a/common/ubiformat.c +++ b/common/ubiformat.c @@ -679,3 +679,64 @@ out_close: return err; } +int ubiformat_write(struct mtd_info *mtd, const void *buf, size_t count, + loff_t offset) +{ + int writesize = mtd->writesize >> mtd->subpage_sft; + size_t retlen; + int ret; + + if (offset & (mtd->writesize - 1)) + return -EINVAL; + + if (count & (mtd->writesize - 1)) + return -EINVAL; + + while (count) { + size_t now; + + now = ALIGN(offset, mtd->erasesize) - offset; + if (now > count) + now = count; + + if (!now) { + const struct ubi_ec_hdr *ec = buf; + const struct ubi_vid_hdr *vid; + + if (be32_to_cpu(ec->magic) != UBI_EC_HDR_MAGIC) { + pr_err("bad UBI magic %#08x, should be %#08x", + be32_to_cpu(ec->magic), UBI_EC_HDR_MAGIC); + return -EINVAL; + } + + /* skip ec header */ + offset += writesize; + buf += writesize; + count -= writesize; + + if (!count) + break; + + vid = buf; + if (be32_to_cpu(vid->magic) != UBI_VID_HDR_MAGIC) { + pr_err("bad UBI magic %#08x, should be %#08x", + be32_to_cpu(vid->magic), UBI_VID_HDR_MAGIC); + return -EINVAL; + } + + continue; + } + + ret = mtd_write(mtd, offset, now, &retlen, buf); + if (ret < 0) + return ret; + if (retlen != now) + return -EIO; + + buf += now; + count -= now; + offset += now; + } + + return 0; +} |