summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Richardson <wfrichar@chromium.org>2011-02-10 19:13:10 -0800
committerBill Richardson <wfrichar@chromium.org>2011-02-10 19:13:10 -0800
commit794d4d44db984759466b5b6779833e2d5281e527 (patch)
treea2a9b8a4fc19276178dcac8889bbeb386a2b2aad
parent31b206f218189d2ecb4b12cf05139bb423877a94 (diff)
downloadvboot-794d4d44db984759466b5b6779833e2d5281e527.tar.gz
New commandline args are clearer, and prepare for compression.
BUG=chromium-os:11488 TEST=none Change-Id: I6ee493037da5746d2db6e840ac6590dd12f37cfe Review URL: http://codereview.chromium.org/6482001
-rw-r--r--firmware/include/bmpblk_header.h3
-rwxr-xr-xtests/bitmaps/TestBmpBlock.py11
-rw-r--r--utility/Makefile11
-rw-r--r--utility/bmpblk_util.c101
-rw-r--r--utility/bmpblk_utility.cc160
-rw-r--r--utility/include/bmpblk_util.h13
6 files changed, 233 insertions, 66 deletions
diff --git a/firmware/include/bmpblk_header.h b/firmware/include/bmpblk_header.h
index 6ca67ef5..0d67a496 100644
--- a/firmware/include/bmpblk_header.h
+++ b/firmware/include/bmpblk_header.h
@@ -94,7 +94,7 @@ typedef struct ImageInfo {
uint32_t width; /* Width of the image */
uint32_t height; /* Height of the image */
uint32_t format; /* File format of the image */
- uint32_t compression; /* Compression method to the image file */
+ uint32_t compression; /* Compression method for the image file */
uint32_t original_size; /* Size of the original uncompressed image */
uint32_t compressed_size; /* Size of the compressed image */
uint32_t reserved;
@@ -118,6 +118,7 @@ typedef enum Compression {
COMPRESS_NONE = 0,
COMPRESS_EFIv1, /* The x86 BIOS only supports this */
COMPRESS_TBD, /* Only on ARM? */
+ MAX_COMPRESS,
} Compression;
__pragma(pack(pop)) /* Support packing for MSVC. */
diff --git a/tests/bitmaps/TestBmpBlock.py b/tests/bitmaps/TestBmpBlock.py
index 9abe72df..77ef4199 100755
--- a/tests/bitmaps/TestBmpBlock.py
+++ b/tests/bitmaps/TestBmpBlock.py
@@ -1,4 +1,8 @@
#!/usr/bin/python -tt
+#
+# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
"""Unit tests for bmpblk_utility.
"""
@@ -21,17 +25,18 @@ class TestBmpBlock(unittest.TestCase):
"""Running with no args should print usage and fail."""
rc, out, err = runprog(prog)
self.assertNotEqual(0, rc)
- self.assertTrue(out.count("Usage:"))
+ self.assertTrue(err.count("missing BMPBLOCK name"))
+ self.assertTrue(out.count("bmpblk_utility"))
def testMissingBmp(self):
"""Missing a bmp specified in the yaml is an error."""
- rc, out, err = runprog(prog, '-c', '-C', 'case_nobmp.yaml', 'FOO')
+ rc, out, err = runprog(prog, '-c', 'case_nobmp.yaml', 'FOO')
self.assertNotEqual(0, rc)
self.assertTrue(err.count("No such file or directory"))
def testInvalidBmp(self):
"""A .bmp file that isn't really a BMP should fail."""
- rc, out, err = runprog(prog, '-c', '-C', 'case_badbmp.yaml', 'FOO')
+ rc, out, err = runprog(prog, '-c', 'case_badbmp.yaml', 'FOO')
self.assertNotEqual(0, rc)
self.assertTrue(err.count("Unsupported image format"))
diff --git a/utility/Makefile b/utility/Makefile
index 8d370094..a424941d 100644
--- a/utility/Makefile
+++ b/utility/Makefile
@@ -59,8 +59,15 @@ ${BUILD_ROOT}/dump_kernel_config: dump_kernel_config.c $(LIBS)
${BUILD_ROOT}/gbb_utility: gbb_utility.cc
$(CXX) -DWITH_UTIL_MAIN $(CFLAGS) $< -o $@
-${BUILD_ROOT}/bmpblk_utility: bmpblk_utility.cc
- $(CXX) -DWITH_UTIL_MAIN -lyaml $(CFLAGS) $< -o $@
+${BUILD_ROOT}/bmpblk_utility.o: bmpblk_utility.cc
+ $(CXX) -DWITH_UTIL_MAIN -lyaml $(CFLAGS) -c $< -o $@
+
+${BUILD_ROOT}/bmpblk_util.o: bmpblk_util.c
+ $(CC) $(CFLAGS) -c $< -o $@
+
+${BUILD_ROOT}/bmpblk_utility: ${BUILD_ROOT}/bmpblk_utility.o \
+ ${BUILD_ROOT}/bmpblk_util.o
+ $(CXX) -DWITH_UTIL_MAIN -lyaml $(CFLAGS) $^ -o $@
${BUILD_ROOT}/load_kernel_test: load_kernel_test.c $(LIBS)
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@ $(LIBS) -lcrypto
diff --git a/utility/bmpblk_util.c b/utility/bmpblk_util.c
new file mode 100644
index 00000000..d7b9cbf8
--- /dev/null
+++ b/utility/bmpblk_util.c
@@ -0,0 +1,101 @@
+// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "bmpblk_util.h"
+
+
+// Returns pointer to buffer containing entire file, sets length.
+static void *read_entire_file(const char *filename, size_t *length) {
+ int fd;
+ struct stat sbuf;
+ void *ptr;
+
+ *length = 0; // just in case
+
+ if (0 != stat(filename, &sbuf)) {
+ fprintf(stderr, "Unable to stat %s: %s\n", filename, strerror(errno));
+ return 0;
+ }
+
+ if (!sbuf.st_size) {
+ fprintf(stderr, "File %s is empty\n", filename);
+ return 0;
+ }
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
+ return 0;
+ }
+
+ ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (MAP_FAILED == ptr) {
+ fprintf(stderr, "Unable to mmap %s: %s\n", filename, strerror(errno));
+ close(fd);
+ return 0;
+ }
+
+ *length = sbuf.st_size;
+
+ close(fd);
+
+ return ptr;
+}
+
+
+// Reclaims buffer from read_entire_file().
+static void discard_file(void *ptr, size_t length) {
+ munmap(ptr, length);
+}
+
+
+// Show what's inside
+int display_bmpblock(const char *infile) {
+ char *ptr;
+ size_t length = 0;
+ BmpBlockHeader *hdr;
+
+ ptr = (char *)read_entire_file(infile, &length);
+ if (!ptr)
+ return 1;
+
+ if (length < sizeof(BmpBlockHeader)) {
+ fprintf(stderr, "File %s is too small to be a BMPBLOCK\n", infile);
+ discard_file(ptr, length);
+ return 1;
+ }
+
+ if (0 != memcmp(ptr, BMPBLOCK_SIGNATURE, BMPBLOCK_SIGNATURE_SIZE)) {
+ fprintf(stderr, "File %s is not a BMPBLOCK\n", infile);
+ discard_file(ptr, length);
+ return 1;
+ }
+
+ hdr = (BmpBlockHeader *)ptr;
+ printf("%s:\n", infile);
+ printf(" version %d.%d\n", hdr->major_version, hdr->minor_version);
+ printf(" %d screens\n", hdr->number_of_screenlayouts);
+ printf(" %d localizations\n", hdr->number_of_localizations);
+ printf(" %d discrete images\n", hdr->number_of_imageinfos);
+
+ discard_file(ptr, length);
+
+ return 0;
+}
+
+int extract_bmpblock(const char *infile, const char *dirname, int force) {
+ printf("extract parts from %s into %s %s overwriting\n",
+ infile, dirname, force ? "with" : "without");
+ printf("NOT YET IMPLEMENTED\n");
+ return 0;
+}
diff --git a/utility/bmpblk_utility.cc b/utility/bmpblk_utility.cc
index 750235cb..f997cf5d 100644
--- a/utility/bmpblk_utility.cc
+++ b/utility/bmpblk_utility.cc
@@ -482,30 +482,41 @@ void BmpBlockUtil::write_to_bmpblock(const char *filename) {
#ifdef WITH_UTIL_MAIN
-///////////////////////////////////////////////////////////////////////
-// Command line utilities
+//////////////////////////////////////////////////////////////////////////////
+// Command line utilities.
+
+extern "C" {
+#include "bmpblk_util.h"
+}
using vboot_reference::BmpBlockUtil;
// utility function: provide usage of this utility and exit.
static void usagehelp_exit(const char *prog_name) {
printf(
- "Utility to manage firmware screen block (BMPBLOCK)\n"
- "Usage: %s -c|-l|-x [options] BMPBLOCK_FILE\n"
"\n"
- "Main Operation Mode:\n"
- " -c, --create Create a new BMPBLOCK file. Should specify --config.\n"
- " -l, --list List the contents of a BMPBLOCK file.\n"
- " -x, --extract Extract embedded images and config file from a BMPBLOCK\n"
- " file.\n"
+ "To create a new BMPBLOCK file using config from YAML file:\n"
"\n"
- "Other Options:\n"
- " -C, --config=CONFIG_FILE Config file describing screen layouts and\n"
- " embedded images. (default: bmpblk.cfg)\n"
+ " %s [-z NUM] -c YAML BMPBLOCK\n"
+ "\n"
+ " -z NUM = compression algorithm to use\n"
+ " 0 = none\n"
+ " 1 = EFIv1\n"
+ " 2 = TBD\n"
+ "\n", prog_name);
+ printf(
+ "To display the contents of a BMPBLOCK:\n"
"\n"
- "Example:\n"
- " %s --create --config=screens.cfg bmpblk.bin\n"
- , prog_name, prog_name);
+ " %s BMPBLOCK\n"
+ "\n", prog_name);
+ printf(
+ "To unpack a BMPBLOCK file:\n"
+ "\n"
+ " %s -x [-d DIR] [-f] BMPBLOCK\n"
+ "\n"
+ " -d DIR = directory to use (default '.')\n"
+ " -f = force overwriting existing files\n"
+ "\n", prog_name);
exit(1);
}
@@ -513,68 +524,97 @@ static void usagehelp_exit(const char *prog_name) {
// main
int main(int argc, char *argv[]) {
- const char *prog_name = argv[0];
- BmpBlockUtil util;
- struct BmpBlockUtilOptions {
- bool create_mode, list_mode, extract_mode;
- string config_fn, bmpblock_fn;
- } options;
-
- int longindex, opt;
- static struct option longopts[] = {
- {"create", 0, NULL, 'c'},
- {"list", 0, NULL, 'l'},
- {"extract", 0, NULL, 'x'},
- {"config", 1, NULL, 'C'},
- { NULL, 0, NULL, 0 },
- };
-
- while ((opt = getopt_long(argc, argv, "clxC:", longopts, &longindex)) >= 0) {
+ const char *prog_name = strrchr(argv[0], '/');
+ if (prog_name)
+ prog_name++;
+ else
+ prog_name = argv[0];
+
+ int force = 0, extract_mode = 0;
+ int compression = 0;
+ const char *config_fn = 0, *bmpblock_fn = 0, *extract_dir = ".";
+
+ int opt;
+ opterr = 0; // quiet
+ int errorcnt = 0;
+ char *e = 0;
+ while ((opt = getopt(argc, argv, ":c:xz:fd:")) != -1) {
switch (opt) {
- case 'c':
- options.create_mode = true;
- break;
- case 'l':
- options.list_mode = true;
- break;
- case 'x':
- options.extract_mode = true;
- break;
- case 'C':
- options.config_fn = optarg;
- break;
- default:
- case '?':
- usagehelp_exit(prog_name);
- break;
+ case 'c':
+ config_fn = optarg;
+ break;
+ case 'x':
+ extract_mode = 1;
+ break;
+ case 'z':
+ compression = (int)strtoul(optarg, &e, 0);
+ if (!*optarg || (e && *e)) {
+ fprintf(stderr, "%s: invalid argument to -%c: \"%s\"\n",
+ prog_name, opt, optarg);
+ errorcnt++;
+ }
+ if (compression >= MAX_COMPRESS) {
+ fprintf(stderr, "%s: compression type must be less than %d\n",
+ prog_name, compression);
+ errorcnt++;
+ }
+ break;
+ case 'f':
+ force = 1;
+ break;
+ case 'd':
+ extract_dir= optarg;
+ break;
+ case ':':
+ fprintf(stderr, "%s: missing argument to -%c\n",
+ prog_name, optopt);
+ errorcnt++;
+ break;
+ default:
+ fprintf(stderr, "%s: unrecognized switch: -%c\n",
+ prog_name, optopt);
+ errorcnt++;
+ break;
}
}
argc -= optind;
argv += optind;
- if (argc == 1) {
- options.bmpblock_fn = argv[0];
+ if (argc >= 1) {
+ bmpblock_fn = argv[0];
} else {
- usagehelp_exit(prog_name);
+ fprintf(stderr, "%s: missing BMPBLOCK name\n", prog_name);
+ errorcnt++;
}
- if (options.create_mode) {
- util.load_from_config(options.config_fn.c_str());
+ if (errorcnt)
+ usagehelp_exit(prog_name);
+
+ BmpBlockUtil util;
+
+ if (config_fn) {
+ printf("compression is %d\n", compression);
+ util.load_from_config(config_fn);
util.pack_bmpblock();
- util.write_to_bmpblock(options.bmpblock_fn.c_str());
+ util.write_to_bmpblock(bmpblock_fn);
printf("The BMPBLOCK is sucessfully created in: %s.\n",
- options.bmpblock_fn.c_str());
+ bmpblock_fn);
}
- if (options.list_mode) {
+ else if (extract_mode) {
+ return extract_bmpblock(bmpblock_fn, extract_dir, force);
+ printf("extract parts from %s into %s %s overwriting\n",
+ bmpblock_fn, extract_dir, force ? "with" : "without");
/* TODO(waihong): Implement the list mode. */
- error("List mode hasn't been implemented yet.\n");
+ error("Extract mode hasn't been implemented yet.\n");
}
- if (options.extract_mode) {
- /* TODO(waihong): Implement the extract mode. */
- error("Extract mode hasn't been implemented yet.\n");
+ else {
+ return display_bmpblock(bmpblock_fn);
+ printf("display content of %s\n", bmpblock_fn);
+ /* TODO(waihong): Implement the list mode. */
+ error("List mode hasn't been implemented yet.\n");
}
return 0;
diff --git a/utility/include/bmpblk_util.h b/utility/include/bmpblk_util.h
new file mode 100644
index 00000000..6a2f92bc
--- /dev/null
+++ b/utility/include/bmpblk_util.h
@@ -0,0 +1,13 @@
+// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef VBOOT_REFERENCE_BMPBLK_UTIL_H_
+#define VBOOT_REFERENCE_BMPBLK_UTIL_H_
+
+#include "bmpblk_header.h"
+
+int display_bmpblock(const char *infile);
+int extract_bmpblock(const char *infile, const char *dirname, int force);
+
+#endif // VBOOT_REFERENCE_BMPBLK_UTIL_H_