It is useful to be able to extract all binaries from the image, or a
subset of them. Add a new 'extract' command to handle this.
Signed-off-by: Simon Glass
---
Changes in v2: None
tools/binman/README | 25 +-
tools/binman/cmdline.py | 13 +++
tools/binman/control.py | 60 +
tools/binman/ftest.py | 189
4 files changed, 286 insertions(+), 1 deletion(-)
diff --git a/tools/binman/README b/tools/binman/README
index 1655a9d50df..756c6a0010e 100644
--- a/tools/binman/README
+++ b/tools/binman/README
@@ -533,6 +533,30 @@ or with wildcards:
image-header bf8 8 image-header bf8
+Extracting files from images
+
+
+You can extract files from an existing firmware image created by binman,
+provided that there is an 'fdtmap' entry in the image. For example:
+
+$ binman extract -i image.bin section/cbfs/u-boot
+
+which will write the uncompressed contents of that entry to the file 'u-boot'
in
+the current directory. You can also extract to a particular file, in this case
+u-boot.bin:
+
+$ binman extract -i image.bin section/cbfs/u-boot -f u-boot.bin
+
+It is possible to extract all files into a destination directory, which will
+put files in subdirectories matching the entry hierarchy:
+
+$ binman extract -i image.bin -O outdir
+
+or just a selection:
+
+$ binman extract -i image.bin "*u-boot*" -O outdir
+
+
Logging
---
@@ -883,7 +907,6 @@ Some ideas:
- Use of-platdata to make the information available to code that is unable
to use device tree (such as a very small SPL image)
- Allow easy building of images by specifying just the board name
-- Add an option to decode an image into the constituent binaries
- Support building an image for a board (-b) more completely, with a
configurable build directory
- Support updating binaries in an image (with no size change / repacking)
diff --git a/tools/binman/cmdline.py b/tools/binman/cmdline.py
index 508232eabb5..a43aec649ed 100644
--- a/tools/binman/cmdline.py
+++ b/tools/binman/cmdline.py
@@ -71,6 +71,19 @@ controlled by a description in the board device tree.'''
list_parser.add_argument('paths', type=str, nargs='*',
help='Paths within file to list (wildcard)')
+extract_parser = subparsers.add_parser('extract',
+ help='Extract files from an image')
+extract_parser.add_argument('-i', '--image', type=str, required=True,
+help='Image filename to extract')
+extract_parser.add_argument('-f', '--filename', type=str,
+help='Output filename to write to')
+extract_parser.add_argument('-O', '--outdir', type=str, default='',
+help='Path to directory to use for output files')
+extract_parser.add_argument('paths', type=str, nargs='*',
+help='Paths within file to extract (wildcard)')
+extract_parser.add_argument('-U', '--uncompressed', action='store_true',
+help='Output raw uncompressed data for compressed entries')
+
test_parser = subparsers.add_parser('test', help='Run tests')
test_parser.add_argument('-P', '--processes', type=int,
help='set number of processes to use for running tests')
diff --git a/tools/binman/control.py b/tools/binman/control.py
index b244e7a0cd0..dc898be6179 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -118,6 +118,57 @@ def ReadEntry(image_fname, entry_path, decomp=True):
return entry.ReadData(decomp)
+def ExtractEntries(image_fname, output_fname, outdir, entry_paths,
+ decomp=True):
+"""Extract the data from one or more entries and write it to files
+
+Args:
+image_fname: Image filename to process
+output_fname: Single output filename to use if extracting one file,
None
+otherwise
+outdir: Output directory to use (for any number of files), else None
+entry_paths: List of entry paths to extract
+decomp: True to compress the entry data
+
+Returns:
+List of EntryInfo records that were written
+"""
+image = Image.FromFile(image_fname)
+
+# Output an entry to a single file, as a special case
+if output_fname:
+if not entry_paths:
+raise ValueError('Must specify an entry path to write with -o')
+if len(entry_paths) != 1:
+raise ValueError('Must specify exactly one entry path to write
with -o')
+entry = image.FindEntryPath(entry_paths[0])
+data = entry.ReadData(decomp)
+tools.WriteFile(output_fname, data)
+tout.Notice("Wrote %#x bytes to file '%s'" % (len(data), output_fname))
+return
+
+# Otherwise we will output to a path given by the entry path of each entry.
+# This means that entries will appear in subdirectories if they are part of
+# a sub-section.