Commit cc734f5ab26134e5e8d57c34edc257c89ac5b1d2

Authored by Paul Burton
Committed by Scott Wood
1 parent dd7185f176

cmd_ubi: add write.part command, to write a volume in multiple parts

This allows you to write data to an UBI volume when the amount of memory
available to write that data from is less than the total size of the
data. For example, you may split a root filesystem UBIFS image into
parts, provide the total size of the image to the first write.part
command and then use multiple write.part commands to write the
subsequent parts of the volume. This results in a sequence of commands
akin to:

  ext4load mmc 0:1 0x80000000 rootfs.ubifs.0
  ubi write.part 0x80000000 root 0x08000000 0x18000000
  ext4load mmc 0:1 0x80000000 rootfs.ubifs.1
  ubi write.part 0x80000000 root 0x08000000
  ext4load mmc 0:1 0x80000000 rootfs.ubifs.2
  ubi write.part 0x80000000 root 0x08000000

This would write 384MiB of data to the UBI volume 'root' whilst only
requiring 128MiB of said data to be held in memory at a time.

Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Acked-by: Stefan Roese <sr@denx.de>

Showing 2 changed files with 51 additions and 15 deletions Side-by-side Diff

... ... @@ -266,28 +266,15 @@
266 266 return err;
267 267 }
268 268  
269   -int ubi_volume_write(char *volume, void *buf, size_t size)
  269 +int ubi_volume_continue_write(char *volume, void *buf, size_t size)
270 270 {
271 271 int err = 1;
272   - int rsvd_bytes = 0;
273 272 struct ubi_volume *vol;
274 273  
275 274 vol = ubi_find_volume(volume);
276 275 if (vol == NULL)
277 276 return ENODEV;
278 277  
279   - rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad);
280   - if (size < 0 || size > rsvd_bytes) {
281   - printf("size > volume size! Aborting!\n");
282   - return EINVAL;
283   - }
284   -
285   - err = ubi_start_update(ubi, vol, size);
286   - if (err < 0) {
287   - printf("Cannot start volume update\n");
288   - return -err;
289   - }
290   -
291 278 err = ubi_more_update_data(ubi, vol, buf, size);
292 279 if (err < 0) {
293 280 printf("Couldnt or partially wrote data\n");
... ... @@ -314,6 +301,37 @@
314 301 return 0;
315 302 }
316 303  
  304 +int ubi_volume_begin_write(char *volume, void *buf, size_t size,
  305 + size_t full_size)
  306 +{
  307 + int err = 1;
  308 + int rsvd_bytes = 0;
  309 + struct ubi_volume *vol;
  310 +
  311 + vol = ubi_find_volume(volume);
  312 + if (vol == NULL)
  313 + return ENODEV;
  314 +
  315 + rsvd_bytes = vol->reserved_pebs * (ubi->leb_size - vol->data_pad);
  316 + if (size < 0 || size > rsvd_bytes) {
  317 + printf("size > volume size! Aborting!\n");
  318 + return EINVAL;
  319 + }
  320 +
  321 + err = ubi_start_update(ubi, vol, full_size);
  322 + if (err < 0) {
  323 + printf("Cannot start volume update\n");
  324 + return -err;
  325 + }
  326 +
  327 + return ubi_volume_continue_write(volume, buf, size);
  328 +}
  329 +
  330 +int ubi_volume_write(char *volume, void *buf, size_t size)
  331 +{
  332 + return ubi_volume_begin_write(volume, buf, size, size);
  333 +}
  334 +
317 335 int ubi_volume_read(char *volume, char *buf, size_t size)
318 336 {
319 337 int err, lnum, off, len, tbuf_size;
... ... @@ -588,7 +606,20 @@
588 606 addr = simple_strtoul(argv[2], NULL, 16);
589 607 size = simple_strtoul(argv[4], NULL, 16);
590 608  
591   - ret = ubi_volume_write(argv[3], (void *)addr, size);
  609 + if (strlen(argv[1]) == 10 &&
  610 + strncmp(argv[1] + 5, ".part", 5) == 0) {
  611 + if (argc < 6) {
  612 + ret = ubi_volume_continue_write(argv[3],
  613 + (void *)addr, size);
  614 + } else {
  615 + size_t full_size;
  616 + full_size = simple_strtoul(argv[5], NULL, 16);
  617 + ret = ubi_volume_begin_write(argv[3],
  618 + (void *)addr, size, full_size);
  619 + }
  620 + } else {
  621 + ret = ubi_volume_write(argv[3], (void *)addr, size);
  622 + }
592 623 if (!ret) {
593 624 printf("%lld bytes written to volume %s\n", size,
594 625 argv[3]);
... ... @@ -636,6 +667,8 @@
636 667 " - create volume name with size\n"
637 668 "ubi write[vol] address volume size"
638 669 " - Write volume from address with size\n"
  670 + "ubi write.part address volume size [fullsize]\n"
  671 + " - Write part of a volume from address\n"
639 672 "ubi read[vol] address volume [size]"
640 673 " - Read volume to address with size\n"
641 674 "ubi remove[vol] volume"
... ... @@ -14,6 +14,8 @@
14 14 ubi info [l[ayout]] - Display volume and ubi layout information
15 15 ubi create[vol] volume [size] [type] - create volume name with size
16 16 ubi write[vol] address volume size - Write volume from address with size
  17 +ubi write.part address volume size [fullsize]
  18 + - Write part of a volume from address
17 19 ubi read[vol] address volume [size] - Read volume to address with size
18 20 ubi remove[vol] volume - Remove volume
19 21 [Legends]
... ... @@ -77,6 +79,7 @@
77 79 ubi removevol Remove UBI volume from UBI device
78 80 ubi read Read data from UBI volume to memory
79 81 ubi write Write data from memory to UBI volume
  82 +ubi write.part Write data from memory to UBI volume, in parts
80 83  
81 84  
82 85 Here a few examples on the usage: