summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Wai-Hong Tam <waihong@google.com>2011-02-17 12:58:58 +0800
committerTom Wai-Hong Tam <waihong@google.com>2011-02-17 12:58:58 +0800
commitee2bc91d4393796721dc8a48d3510e3352f2b893 (patch)
tree87df9e47236b4949aec9760e7b0b92f33934635a
parent686dd5cefb172968b8491a941d124fbfeefe230f (diff)
downloadvboot-ee2bc91d4393796721dc8a48d3510e3352f2b893.tar.gz
Enable LZMA compression in bmpbklk_utility.
LZMA has better compression ratio and is also supported in u-boot already. ARM BIOS will use LZMA to compress BMP files. BUG=chromium-os:11017 TEST=manual $ make $ make runbmptests Change-Id: I6b791e3284b65eb3085b0de548bd241eab2ee598 Review URL: http://codereview.chromium.org/6523019
-rw-r--r--firmware/include/bmpblk_header.h2
-rwxr-xr-xtests/bitmaps/TestBmpBlock.py16
-rw-r--r--utility/Makefile4
-rw-r--r--utility/bmpblk_util.c57
-rw-r--r--utility/bmpblk_utility.cc35
5 files changed, 105 insertions, 9 deletions
diff --git a/firmware/include/bmpblk_header.h b/firmware/include/bmpblk_header.h
index 0d67a496..0c609dd2 100644
--- a/firmware/include/bmpblk_header.h
+++ b/firmware/include/bmpblk_header.h
@@ -117,7 +117,7 @@ typedef enum ImageFormat {
typedef enum Compression {
COMPRESS_NONE = 0,
COMPRESS_EFIv1, /* The x86 BIOS only supports this */
- COMPRESS_TBD, /* Only on ARM? */
+ COMPRESS_LZMA1, /* The ARM BIOS supports LZMA1 */
MAX_COMPRESS,
} Compression;
diff --git a/tests/bitmaps/TestBmpBlock.py b/tests/bitmaps/TestBmpBlock.py
index ced270ee..be815929 100755
--- a/tests/bitmaps/TestBmpBlock.py
+++ b/tests/bitmaps/TestBmpBlock.py
@@ -89,19 +89,27 @@ class TestPackUnpack(unittest.TestCase):
self.assertEqual(0, rc)
os.chdir('..')
- def testPackUnpackZ(self):
- """Create, unpack, recreate with explicit compression"""
- rc, out, err = runprog(prog, '-z', '1', '-c', 'case_simple.yaml', 'FOO')
+ def doPackUnpackZ(self, comp):
+ """Create, unpack, recreate with a given compression"""
+ rc, out, err = runprog(prog, '-z', comp, '-c', 'case_simple.yaml', 'FOO')
self.assertEqual(0, rc)
rc, out, err = runprog(prog, '-x', '-d', './FOO_DIR', 'FOO')
self.assertEqual(0, rc)
os.chdir('./FOO_DIR')
- rc, out, err = runprog(prog, '-z', '1', '-c', 'config.yaml', 'BAR')
+ rc, out, err = runprog(prog, '-z', comp, '-c', 'config.yaml', 'BAR')
self.assertEqual(0, rc)
rc, out, err = runprog('/usr/bin/cmp', '../FOO', 'BAR')
self.assertEqual(0, rc)
os.chdir('..')
+ def testPackUnpackZ1(self):
+ """Create, unpack, recreate with EFIv1 compression"""
+ self.doPackUnpackZ('1');
+
+ def testPackUnpackZ2(self):
+ """Create, unpack, recreate with LZMA compression"""
+ self.doPackUnpackZ('2');
+
def tearDown(self):
rc, out, err = runprog('/bin/rm', '-rf', './FOO_DIR', 'FOO')
self.assertEqual(0, rc)
diff --git a/utility/Makefile b/utility/Makefile
index af0187b3..8ea53a62 100644
--- a/utility/Makefile
+++ b/utility/Makefile
@@ -60,7 +60,7 @@ ${BUILD_ROOT}/gbb_utility: gbb_utility.cc
$(CXX) -DWITH_UTIL_MAIN $(CFLAGS) $< -o $@
${BUILD_ROOT}/bmpblk_utility.o: bmpblk_utility.cc
- $(CXX) -DWITH_UTIL_MAIN -lyaml $(CFLAGS) -c $< -o $@
+ $(CXX) -DWITH_UTIL_MAIN $(CFLAGS) -c $< -o $@
${BUILD_ROOT}/bmpblk_util.o: bmpblk_util.c
$(CC) $(CFLAGS) -c $< -o $@
@@ -75,7 +75,7 @@ ${BUILD_ROOT}/bmpblk_utility: ${BUILD_ROOT}/bmpblk_utility.o \
${BUILD_ROOT}/bmpblk_util.o \
${BUILD_ROOT}/eficompress.o \
${BUILD_ROOT}/efidecompress.o
- $(CXX) -DWITH_UTIL_MAIN -lyaml $(CFLAGS) $^ -o $@
+ $(CXX) -llzma -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
index 214beda4..f2b0adc8 100644
--- a/utility/bmpblk_util.c
+++ b/utility/bmpblk_util.c
@@ -5,6 +5,7 @@
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
+#include <lzma.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
@@ -99,7 +100,7 @@ static void *do_efi_decompress(ImageInfo *img) {
uint32_t osize;
EFI_STATUS r;
- ibuf = ((void *)img) + sizeof(ImageInfo);
+ ibuf = (void*)(img + 1);
isize = img->compressed_size;
r = EfiGetInfo(ibuf, isize, &osize, &ssize);
@@ -139,6 +140,50 @@ static void *do_efi_decompress(ImageInfo *img) {
}
+
+static void *do_lzma_decompress(ImageInfo *img) {
+ void *ibuf;
+ void *obuf;
+ uint32_t isize;
+ uint32_t osize;
+ lzma_stream stream = LZMA_STREAM_INIT;
+ lzma_ret result;
+
+ ibuf = (void*)(img + 1);
+ isize = img->compressed_size;
+ osize = img->original_size;
+ obuf = malloc(osize);
+ if (!obuf) {
+ fprintf(stderr, "Can't allocate %d bytes: %s\n",
+ osize,
+ strerror(errno));
+ return 0;
+ }
+
+ result = lzma_auto_decoder(&stream, -1, 0);
+ if (result != LZMA_OK) {
+ fprintf(stderr, "Unable to initialize auto decoder (error: %d)!\n",
+ result);
+ free(obuf);
+ return 0;
+ }
+
+ stream.next_in = ibuf;
+ stream.avail_in = isize;
+ stream.next_out = obuf;
+ stream.avail_out = osize;
+ result = lzma_code(&stream, LZMA_FINISH);
+ if (result != LZMA_STREAM_END) {
+ fprintf(stderr, "Unalbe to decode data (error: %d)!\n", result);
+ free(obuf);
+ return 0;
+ }
+ lzma_end(&stream);
+ return obuf;
+}
+
+
+
// Show what's inside. If todir is NULL, just print. Otherwise unpack.
int dump_bmpblock(const char *infile, int show_as_yaml,
const char *todir, int overwrite) {
@@ -266,6 +311,16 @@ int dump_bmpblock(const char *infile, int show_as_yaml,
}
free_data = 1;
break;
+ case COMPRESS_LZMA1:
+ data_ptr = do_lzma_decompress(img);
+ if (!data_ptr) {
+ fclose(bfp);
+ fclose(yfp);
+ discard_file(ptr, length);
+ return 1;
+ }
+ free_data = 1;
+ break;
default:
fprintf(stderr, "Unsupported compression method encountered.\n");
fclose(bfp);
diff --git a/utility/bmpblk_utility.cc b/utility/bmpblk_utility.cc
index 9f912d0b..c9188a8e 100644
--- a/utility/bmpblk_utility.cc
+++ b/utility/bmpblk_utility.cc
@@ -10,6 +10,7 @@
#include <assert.h>
#include <errno.h>
#include <getopt.h>
+#include <lzma.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -326,6 +327,38 @@ void BmpBlockUtil::load_all_image_files() {
free(tmpbuf);
}
break;
+ case COMPRESS_LZMA1:
+ {
+ // Calculate the worst case of buffer size.
+ uint32_t tmpsize = lzma_stream_buffer_bound(content.size());
+ uint8_t *tmpbuf = (uint8_t *)malloc(tmpsize);
+ lzma_stream stream = LZMA_STREAM_INIT;
+ lzma_options_lzma options;
+ lzma_ret result;
+
+ lzma_lzma_preset(&options, 9);
+ result = lzma_alone_encoder(&stream, &options);
+ if (result != LZMA_OK) {
+ error("Unable to initialize easy encoder (error: %d)!\n", result);
+ }
+
+ stream.next_in = (uint8_t *)content.data();
+ stream.avail_in = content.size();
+ stream.next_out = tmpbuf;
+ stream.avail_out = tmpsize;
+ result = lzma_code(&stream, LZMA_FINISH);
+ if (result != LZMA_STREAM_END) {
+ error("Unable to encode data (error: %d)!\n", result);
+ }
+
+ it->second.data.compression = compression_;
+ it->second.compressed_content.assign((const char *)tmpbuf,
+ tmpsize - stream.avail_out);
+ it->second.data.compressed_size = tmpsize - stream.avail_out;
+ lzma_end(&stream);
+ free(tmpbuf);
+ }
+ break;
default:
error("Unsupported compression method attempted.\n");
}
@@ -535,7 +568,7 @@ static void usagehelp_exit(const char *prog_name) {
" -z NUM = compression algorithm to use\n"
" 0 = none\n"
" 1 = EFIv1\n"
- " 2 = TBD\n"
+ " 2 = LZMA1\n"
"\n", prog_name);
printf(
"To display the contents of a BMPBLOCK:\n"