2 * Copyright (c) 2013, The Chromium Authors
4 * SPDX-License-Identifier: GPL-2.0+
16 #include <u-boot/zlib.h>
19 #include <lzma/LzmaTypes.h>
20 #include <lzma/LzmaDec.h>
21 #include <lzma/LzmaTools.h>
23 #include <linux/lzo.h>
25 static const char plain[] =
26 "I am a highly compressable bit of text.\n"
27 "I am a highly compressable bit of text.\n"
28 "I am a highly compressable bit of text.\n"
29 "There are many like me, but this one is mine.\n"
30 "If I were any shorter, there wouldn't be much sense in\n"
31 "compressing me in the first place. At least with lzo, anyway,\n"
32 "which appears to behave poorly in the face of short text\n"
35 /* bzip2 -c /tmp/plain.txt > /tmp/plain.bz2 */
36 static const char bzip2_compressed[] =
37 "\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\xe5\x63\xdd\x09\x00\x00"
38 "\x28\x57\x80\x00\x10\x40\x85\x20\x20\x04\x00\x3f\xef\xdf\xf0\x30"
39 "\x00\xd6\xd0\x34\x91\x89\xa6\xf5\x4d\x19\x1a\x19\x0d\x02\x34\xd4"
40 "\xc9\x00\x34\x34\x00\x02\x48\x41\x35\x4f\xd4\xc6\x88\xd3\x50\x3d"
41 "\x4f\x51\x82\x4f\x88\xc3\x0d\x05\x62\x4f\x91\xa3\x52\x1b\xd0\x52"
42 "\x41\x4a\xa3\x98\xc2\x6b\xca\xa3\x82\xa5\xac\x8b\x15\x99\x68\xad"
43 "\xdf\x29\xd6\xf1\xf7\x5a\x10\xcd\x8c\x26\x61\x94\x95\xfe\x9e\x16"
44 "\x18\x28\x69\xd4\x23\x64\xcc\x2b\xe5\xe8\x5f\x00\xa4\x70\x26\x2c"
45 "\xee\xbd\x59\x6d\x6a\xec\xfc\x31\xda\x59\x0a\x14\x2a\x60\x1c\xf0"
46 "\x04\x86\x73\x9a\xc5\x5b\x87\x3f\x5b\x4c\x93\xe6\xb5\x35\x0d\xa6"
47 "\xb1\x2e\x62\x7b\xab\x67\xe7\x99\x2a\x14\x5e\x9f\x64\xcb\x96\xf4"
48 "\x0d\x65\xd4\x39\xe6\x8b\x7e\xea\x1c\x03\x69\x97\x83\x58\x91\x96"
49 "\xe1\xf0\x9d\xa4\x15\x8b\xb8\xc6\x93\xdc\x3d\xd9\x3c\x22\x55\xef"
50 "\xfb\xbb\x2a\xd3\x87\xa2\x8b\x04\xd9\x19\xf8\xe2\xfd\x4f\xdb\x1a"
51 "\x07\xc8\x60\xa3\x3f\xf8\xbb\x92\x29\xc2\x84\x87\x2b\x1e\xe8\x48";
52 static const unsigned long bzip2_compressed_size = 240;
54 /* lzma -z -c /tmp/plain.txt > /tmp/plain.lzma */
55 static const char lzma_compressed[] =
56 "\x5d\x00\x00\x80\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x24\x88"
57 "\x08\x26\xd8\x41\xff\x99\xc8\xcf\x66\x3d\x80\xac\xba\x17\xf1\xc8"
58 "\xb9\xdf\x49\x37\xb1\x68\xa0\x2a\xdd\x63\xd1\xa7\xa3\x66\xf8\x15"
59 "\xef\xa6\x67\x8a\x14\x18\x80\xcb\xc7\xb1\xcb\x84\x6a\xb2\x51\x16"
60 "\xa1\x45\xa0\xd6\x3e\x55\x44\x8a\x5c\xa0\x7c\xe5\xa8\xbd\x04\x57"
61 "\x8f\x24\xfd\xb9\x34\x50\x83\x2f\xf3\x46\x3e\xb9\xb0\x00\x1a\xf5"
62 "\xd3\x86\x7e\x8f\x77\xd1\x5d\x0e\x7c\xe1\xac\xde\xf8\x65\x1f\x4d"
63 "\xce\x7f\xa7\x3d\xaa\xcf\x26\xa7\x58\x69\x1e\x4c\xea\x68\x8a\xe5"
64 "\x89\xd1\xdc\x4d\xc7\xe0\x07\x42\xbf\x0c\x9d\x06\xd7\x51\xa2\x0b"
65 "\x7c\x83\x35\xe1\x85\xdf\xee\xfb\xa3\xee\x2f\x47\x5f\x8b\x70\x2b"
66 "\xe1\x37\xf3\x16\xf6\x27\x54\x8a\x33\x72\x49\xea\x53\x7d\x60\x0b"
67 "\x21\x90\x66\xe7\x9e\x56\x61\x5d\xd8\xdc\x59\xf0\xac\x2f\xd6\x49"
68 "\x6b\x85\x40\x08\x1f\xdf\x26\x25\x3b\x72\x44\xb0\xb8\x21\x2f\xb3"
69 "\xd7\x9b\x24\x30\x78\x26\x44\x07\xc3\x33\xd1\x4d\x03\x1b\xe1\xff"
70 "\xfd\xf5\x50\x8d\xca";
71 static const unsigned long lzma_compressed_size = 229;
73 /* lzop -c /tmp/plain.txt > /tmp/plain.lzo */
74 static const char lzo_compressed[] =
75 "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a\x10\x30\x20\x60\x09\x40\x01"
76 "\x05\x03\x00\x00\x09\x00\x00\x81\xb4\x52\x09\x54\xf1\x00\x00\x00"
77 "\x00\x09\x70\x6c\x61\x69\x6e\x2e\x74\x78\x74\x65\xb1\x07\x9c\x00"
78 "\x00\x01\x5e\x00\x00\x01\x0f\xc3\xc7\x7a\xe0\x00\x16\x49\x20\x61"
79 "\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
80 "\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
81 "\x65\x78\x74\x2e\x0a\x20\x2f\x9c\x00\x00\x22\x54\x68\x65\x72\x65"
82 "\x20\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d"
83 "\x65\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20"
84 "\x69\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x84"
85 "\x06\x0a\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x90"
86 "\x08\x00\x08\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d"
87 "\x75\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xf8\x19\x02"
88 "\x69\x6e\x67\x20\x6d\x64\x02\x64\x06\x00\x5a\x20\x66\x69\x72\x73"
89 "\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
90 "\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x20\x61\x6e\x79\x77"
91 "\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
92 "\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
93 "\x6c\x79\x20\x69\x6e\x20\x74\x68\x65\x20\x66\x61\x63\x65\x20\x6f"
94 "\x66\x20\x73\x68\x6f\x72\x74\x20\x74\x65\x78\x74\x0a\x6d\x65\x73"
95 "\x73\x61\x67\x65\x73\x2e\x0a\x11\x00\x00\x00\x00\x00\x00";
96 static const unsigned long lzo_compressed_size = 334;
99 #define TEST_BUFFER_SIZE 512
101 typedef int (*mutate_func)(void *, unsigned long, void *, unsigned long,
104 static int compress_using_gzip(void *in, unsigned long in_size,
105 void *out, unsigned long out_max,
106 unsigned long *out_size)
109 unsigned long inout_size = out_max;
111 ret = gzip(out, &inout_size, in, in_size);
113 *out_size = inout_size;
118 static int uncompress_using_gzip(void *in, unsigned long in_size,
119 void *out, unsigned long out_max,
120 unsigned long *out_size)
123 unsigned long inout_size = in_size;
125 ret = gunzip(out, out_max, in, &inout_size);
127 *out_size = inout_size;
132 static int compress_using_bzip2(void *in, unsigned long in_size,
133 void *out, unsigned long out_max,
134 unsigned long *out_size)
136 /* There is no bzip2 compression in u-boot, so fake it. */
137 assert(in_size == strlen(plain));
138 assert(memcmp(plain, in, in_size) == 0);
140 if (bzip2_compressed_size > out_max)
143 memcpy(out, bzip2_compressed, bzip2_compressed_size);
145 *out_size = bzip2_compressed_size;
150 static int uncompress_using_bzip2(void *in, unsigned long in_size,
151 void *out, unsigned long out_max,
152 unsigned long *out_size)
155 unsigned int inout_size = out_max;
157 ret = BZ2_bzBuffToBuffDecompress(out, &inout_size, in, in_size,
158 CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
160 *out_size = inout_size;
162 return (ret != BZ_OK);
165 static int compress_using_lzma(void *in, unsigned long in_size,
166 void *out, unsigned long out_max,
167 unsigned long *out_size)
169 /* There is no lzma compression in u-boot, so fake it. */
170 assert(in_size == strlen(plain));
171 assert(memcmp(plain, in, in_size) == 0);
173 if (lzma_compressed_size > out_max)
176 memcpy(out, lzma_compressed, lzma_compressed_size);
178 *out_size = lzma_compressed_size;
183 static int uncompress_using_lzma(void *in, unsigned long in_size,
184 void *out, unsigned long out_max,
185 unsigned long *out_size)
188 SizeT inout_size = out_max;
190 ret = lzmaBuffToBuffDecompress(out, &inout_size, in, in_size);
192 *out_size = inout_size;
194 return (ret != SZ_OK);
197 static int compress_using_lzo(void *in, unsigned long in_size,
198 void *out, unsigned long out_max,
199 unsigned long *out_size)
201 /* There is no lzo compression in u-boot, so fake it. */
202 assert(in_size == strlen(plain));
203 assert(memcmp(plain, in, in_size) == 0);
205 if (lzo_compressed_size > out_max)
208 memcpy(out, lzo_compressed, lzo_compressed_size);
210 *out_size = lzo_compressed_size;
215 static int uncompress_using_lzo(void *in, unsigned long in_size,
216 void *out, unsigned long out_max,
217 unsigned long *out_size)
220 size_t input_size = in_size;
221 size_t output_size = out_max;
223 ret = lzop_decompress(in, input_size, out, &output_size);
225 *out_size = output_size;
227 return (ret != LZO_E_OK);
230 #define errcheck(statement) if (!(statement)) { \
231 fprintf(stderr, "\tFailed: %s\n", #statement); \
236 static int run_test(char *name, mutate_func compress, mutate_func uncompress)
238 ulong orig_size, compressed_size, uncompressed_size;
240 void *compressed_buf = NULL;
241 void *uncompressed_buf = NULL;
242 void *compare_buf = NULL;
245 printf(" testing %s ...\n", name);
247 orig_buf = (void *)plain;
248 orig_size = strlen(orig_buf); /* Trailing NULL not included. */
249 errcheck(orig_size > 0);
251 compressed_size = uncompressed_size = TEST_BUFFER_SIZE;
252 compressed_buf = malloc(compressed_size);
253 errcheck(compressed_buf != NULL);
254 uncompressed_buf = malloc(uncompressed_size);
255 errcheck(uncompressed_buf != NULL);
256 compare_buf = malloc(uncompressed_size);
257 errcheck(compare_buf != NULL);
259 /* Compress works as expected. */
260 printf("\torig_size:%lu\n", orig_size);
261 memset(compressed_buf, 'A', TEST_BUFFER_SIZE);
262 errcheck(compress(orig_buf, orig_size,
263 compressed_buf, compressed_size,
264 &compressed_size) == 0);
265 printf("\tcompressed_size:%lu\n", compressed_size);
266 errcheck(compressed_size > 0);
267 errcheck(compressed_size < orig_size);
268 errcheck(((char *)compressed_buf)[compressed_size-1] != 'A');
269 errcheck(((char *)compressed_buf)[compressed_size] == 'A');
271 /* Uncompresses with space remaining. */
272 errcheck(uncompress(compressed_buf, compressed_size,
273 uncompressed_buf, uncompressed_size,
274 &uncompressed_size) == 0);
275 printf("\tuncompressed_size:%lu\n", uncompressed_size);
276 errcheck(uncompressed_size == orig_size);
277 errcheck(memcmp(orig_buf, uncompressed_buf, orig_size) == 0);
279 /* Uncompresses with exactly the right size output buffer. */
280 memset(uncompressed_buf, 'A', TEST_BUFFER_SIZE);
281 errcheck(uncompress(compressed_buf, compressed_size,
282 uncompressed_buf, orig_size,
283 &uncompressed_size) == 0);
284 errcheck(uncompressed_size == orig_size);
285 errcheck(memcmp(orig_buf, uncompressed_buf, orig_size) == 0);
286 errcheck(((char *)uncompressed_buf)[orig_size] == 'A');
288 /* Make sure compression does not over-run. */
289 memset(compare_buf, 'A', TEST_BUFFER_SIZE);
290 ret = compress(orig_buf, orig_size,
291 compare_buf, compressed_size - 1,
293 errcheck(((char *)compare_buf)[compressed_size] == 'A');
295 printf("\tcompress does not overrun\n");
297 /* Make sure decompression does not over-run. */
298 memset(compare_buf, 'A', TEST_BUFFER_SIZE);
299 ret = uncompress(compressed_buf, compressed_size,
300 compare_buf, uncompressed_size - 1,
302 errcheck(((char *)compare_buf)[uncompressed_size - 1] == 'A');
304 printf("\tuncompress does not overrun\n");
306 /* Got here, everything is fine. */
310 printf(" %s: %s\n", name, ret == 0 ? "ok" : "FAILED");
313 free(uncompressed_buf);
314 free(compressed_buf);
319 static int do_ut_compression(cmd_tbl_t *cmdtp, int flag, int argc,
324 err += run_test("gzip", compress_using_gzip, uncompress_using_gzip);
325 err += run_test("bzip2", compress_using_bzip2, uncompress_using_bzip2);
326 err += run_test("lzma", compress_using_lzma, uncompress_using_lzma);
327 err += run_test("lzo", compress_using_lzo, uncompress_using_lzo);
329 printf("ut_compression %s\n", err == 0 ? "ok" : "FAILED");
334 static int compress_using_none(void *in, unsigned long in_size,
335 void *out, unsigned long out_max,
336 unsigned long *out_size)
338 /* Here we just copy */
339 memcpy(out, in, in_size);
346 * run_bootm_test() - Run tests on the bootm decopmression function
348 * @comp_type: Compression type to test
349 * @compress: Our function to compress data
350 * @return 0 if OK, non-zero on failure
352 static int run_bootm_test(int comp_type, mutate_func compress)
354 ulong compress_size = 1024;
358 const ulong image_start = 0;
359 const ulong load_addr = 0x1000;
362 printf("Testing: %s\n", genimg_get_comp_name(comp_type));
363 compress_buff = map_sysmem(image_start, 0);
364 unc_len = strlen(plain);
365 compress((void *)plain, unc_len, compress_buff, compress_size,
367 err = bootm_decomp_image(comp_type, load_addr, image_start,
368 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
369 compress_buff, compress_size, unc_len,
373 err = bootm_decomp_image(comp_type, load_addr, image_start,
374 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
375 compress_buff, compress_size, unc_len - 1,
380 /* We can't detect corruption when not decompressing */
381 if (comp_type == IH_COMP_NONE)
383 memset(compress_buff + compress_size / 2, '\x49',
385 err = bootm_decomp_image(comp_type, load_addr, image_start,
386 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
387 compress_buff, compress_size, 0x10000,
395 static int do_ut_image_decomp(cmd_tbl_t *cmdtp, int flag, int argc,
400 err = run_bootm_test(IH_COMP_GZIP, compress_using_gzip);
401 err |= run_bootm_test(IH_COMP_BZIP2, compress_using_bzip2);
402 err |= run_bootm_test(IH_COMP_LZMA, compress_using_lzma);
403 err |= run_bootm_test(IH_COMP_LZO, compress_using_lzo);
404 err |= run_bootm_test(IH_COMP_NONE, compress_using_none);
406 printf("ut_image_decomp %s\n", err == 0 ? "ok" : "FAILED");
412 ut_compression, 5, 1, do_ut_compression,
413 "Basic test of compressors: gzip bzip2 lzma lzo", ""
417 ut_image_decomp, 5, 1, do_ut_image_decomp,
418 "Basic test of bootm decompression", ""