Merge "lpmake: Add an option for including partition data in sparse images."
diff --git a/partition_tools/README.md b/partition_tools/README.md
index 0993ce2..44c10e4 100644
--- a/partition_tools/README.md
+++ b/partition_tools/README.md
@@ -19,7 +19,8 @@
* `--alignment=N` - By default, lpmake will align partitions to 1MiB boundaries. However, an alternate alignment can be specified if desired. This is useful for devices with a minimum I/O request size where mis-aligned partition boundaries could be a performance issue.
* `--alignment-offset=N` - In some cases, the "super" partition is misaligned within its parent block device. This offset can be used to correct for that.
* `--sparse` - If set, the output image will be in sparse format for flashing with fastboot. Otherwise, by default, the image will be a minimal format usable with lpdump and lpflash.
-* `-b,--block-size=N` - When writing sparse files, the device may require a specific block size. That block size can be specified here. The alignment must be a multiple of the block size. By default the block size is 4096.
+* `-b,--block-size=N` - When writing a sparse image, the device may require a specific block size. That block size can be specified here. The alignment must be a multiple of the block size. By default the block size is 4096.
+* `-i,--image=[NAME=FILE]` - When writing a sparse image, include the contents of FILE as the data for the partition named NAME. The file can be a normal file or a sparse image, but the destination size must be less than or equal to the partition size. This option is only available when creating sparse images.
Example usage. This specifies a 10GB super partition for an A/B device, with a single 64MiB "cache" partition.
@@ -28,7 +29,8 @@
--metadata-size 65536 \
--metadata-slots 2 \
-o /tmp/super.img \
- -p "cache:2da85788-f0e1-4fda-9ee7-e5177eab184b:none:67108864"
+ -p "cache:2da85788-f0e1-4fda-9ee7-e5177eab184b:none:67108864" \
+ -i "cache=out/target/hikey960/cache.img"
```
## lpdump
diff --git a/partition_tools/lpmake.cc b/partition_tools/lpmake.cc
index 2513344..9ba688d 100644
--- a/partition_tools/lpmake.cc
+++ b/partition_tools/lpmake.cc
@@ -49,6 +49,9 @@
" -a,--alignment=N Optimal partition alignment in bytes.\n"
" -O,--alignment-offset=N Alignment offset in bytes to device parent.\n"
" -S,--sparse Output a sparse image for fastboot.\n"
+ " -i,--image=PARTITION=FILE If building a sparse image for fastboot, include\n"
+ " the given file (or sparse file) as initial data for\n"
+ " the named partition.\n"
"\n"
"Partition data format:\n"
" <name>:<guid>:<attributes>:<size>\n"
@@ -69,6 +72,7 @@
{ "alignment", required_argument, nullptr, 'a' },
{ "sparse", no_argument, nullptr, 'S' },
{ "block-size", required_argument, nullptr, 'b' },
+ { "image", required_argument, nullptr, 'i' },
{ nullptr, 0, nullptr, 0 },
};
@@ -80,6 +84,7 @@
uint32_t block_size = 4096;
std::string output_path;
std::vector<std::string> partitions;
+ std::map<std::string, std::string> images;
bool output_sparse = false;
int rv;
@@ -133,6 +138,20 @@
return EX_USAGE;
}
break;
+ case 'i':
+ {
+ char* separator = strchr(optarg, '=');
+ if (!separator || separator == optarg || !strlen(separator + 1)) {
+ fprintf(stderr, "Expected PARTITION=FILE.\n");
+ return EX_USAGE;
+ }
+ *separator = '\0';
+
+ std::string partition_name(optarg);
+ std::string file(separator + 1);
+ images[partition_name] = file;
+ break;
+ }
default:
break;
}
@@ -164,6 +183,10 @@
fprintf(stderr, "Partition table must have at least one entry.\n");
return EX_USAGE;
}
+ if (!images.empty() && !output_sparse) {
+ fprintf(stderr, "Cannot write partition data for non-sparse images.\n");
+ return EX_USAGE;
+ }
BlockDeviceInfo device_info(blockdevice_size, alignment, alignment_offset);
@@ -208,7 +231,7 @@
std::unique_ptr<LpMetadata> metadata = builder->Export();
if (output_sparse) {
- if (!WriteToSparseFile(output_path.c_str(), *metadata.get(), block_size)) {
+ if (!WriteToSparseFile(output_path.c_str(), *metadata.get(), block_size, images)) {
return EX_CANTCREAT;
}
} else if (!WriteToImageFile(output_path.c_str(), *metadata.get())) {