2 * Copyright (c) 2013, The Chromium Authors
4 * SPDX-License-Identifier: GPL-2.0+
15 #include <u-boot/zlib.h>
18 #include <lzma/LzmaTypes.h>
19 #include <lzma/LzmaDec.h>
20 #include <lzma/LzmaTools.h>
22 #include <linux/lzo.h>
24 static const char plain[] =
25 "I am a highly compressable bit of text.\n"
26 "I am a highly compressable bit of text.\n"
27 "I am a highly compressable bit of text.\n"
28 "There are many like me, but this one is mine.\n"
29 "If I were any shorter, there wouldn't be much sense in\n"
30 "compressing me in the first place. At least with lzo, anyway,\n"
31 "which appears to behave poorly in the face of short text\n"
34 /* bzip2 -c /tmp/plain.txt > /tmp/plain.bz2 */
35 static const char bzip2_compressed[] =
36 "\x42\x5a\x68\x39\x31\x41\x59\x26\x53\x59\xe5\x63\xdd\x09\x00\x00"
37 "\x28\x57\x80\x00\x10\x40\x85\x20\x20\x04\x00\x3f\xef\xdf\xf0\x30"
38 "\x00\xd6\xd0\x34\x91\x89\xa6\xf5\x4d\x19\x1a\x19\x0d\x02\x34\xd4"
39 "\xc9\x00\x34\x34\x00\x02\x48\x41\x35\x4f\xd4\xc6\x88\xd3\x50\x3d"
40 "\x4f\x51\x82\x4f\x88\xc3\x0d\x05\x62\x4f\x91\xa3\x52\x1b\xd0\x52"
41 "\x41\x4a\xa3\x98\xc2\x6b\xca\xa3\x82\xa5\xac\x8b\x15\x99\x68\xad"
42 "\xdf\x29\xd6\xf1\xf7\x5a\x10\xcd\x8c\x26\x61\x94\x95\xfe\x9e\x16"
43 "\x18\x28\x69\xd4\x23\x64\xcc\x2b\xe5\xe8\x5f\x00\xa4\x70\x26\x2c"
44 "\xee\xbd\x59\x6d\x6a\xec\xfc\x31\xda\x59\x0a\x14\x2a\x60\x1c\xf0"
45 "\x04\x86\x73\x9a\xc5\x5b\x87\x3f\x5b\x4c\x93\xe6\xb5\x35\x0d\xa6"
46 "\xb1\x2e\x62\x7b\xab\x67\xe7\x99\x2a\x14\x5e\x9f\x64\xcb\x96\xf4"
47 "\x0d\x65\xd4\x39\xe6\x8b\x7e\xea\x1c\x03\x69\x97\x83\x58\x91\x96"
48 "\xe1\xf0\x9d\xa4\x15\x8b\xb8\xc6\x93\xdc\x3d\xd9\x3c\x22\x55\xef"
49 "\xfb\xbb\x2a\xd3\x87\xa2\x8b\x04\xd9\x19\xf8\xe2\xfd\x4f\xdb\x1a"
50 "\x07\xc8\x60\xa3\x3f\xf8\xbb\x92\x29\xc2\x84\x87\x2b\x1e\xe8\x48";
51 static const unsigned long bzip2_compressed_size = 240;
53 /* lzma -z -c /tmp/plain.txt > /tmp/plain.lzma */
54 static const char lzma_compressed[] =
55 "\x5d\x00\x00\x80\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x24\x88"
56 "\x08\x26\xd8\x41\xff\x99\xc8\xcf\x66\x3d\x80\xac\xba\x17\xf1\xc8"
57 "\xb9\xdf\x49\x37\xb1\x68\xa0\x2a\xdd\x63\xd1\xa7\xa3\x66\xf8\x15"
58 "\xef\xa6\x67\x8a\x14\x18\x80\xcb\xc7\xb1\xcb\x84\x6a\xb2\x51\x16"
59 "\xa1\x45\xa0\xd6\x3e\x55\x44\x8a\x5c\xa0\x7c\xe5\xa8\xbd\x04\x57"
60 "\x8f\x24\xfd\xb9\x34\x50\x83\x2f\xf3\x46\x3e\xb9\xb0\x00\x1a\xf5"
61 "\xd3\x86\x7e\x8f\x77\xd1\x5d\x0e\x7c\xe1\xac\xde\xf8\x65\x1f\x4d"
62 "\xce\x7f\xa7\x3d\xaa\xcf\x26\xa7\x58\x69\x1e\x4c\xea\x68\x8a\xe5"
63 "\x89\xd1\xdc\x4d\xc7\xe0\x07\x42\xbf\x0c\x9d\x06\xd7\x51\xa2\x0b"
64 "\x7c\x83\x35\xe1\x85\xdf\xee\xfb\xa3\xee\x2f\x47\x5f\x8b\x70\x2b"
65 "\xe1\x37\xf3\x16\xf6\x27\x54\x8a\x33\x72\x49\xea\x53\x7d\x60\x0b"
66 "\x21\x90\x66\xe7\x9e\x56\x61\x5d\xd8\xdc\x59\xf0\xac\x2f\xd6\x49"
67 "\x6b\x85\x40\x08\x1f\xdf\x26\x25\x3b\x72\x44\xb0\xb8\x21\x2f\xb3"
68 "\xd7\x9b\x24\x30\x78\x26\x44\x07\xc3\x33\xd1\x4d\x03\x1b\xe1\xff"
69 "\xfd\xf5\x50\x8d\xca";
70 static const unsigned long lzma_compressed_size = 229;
72 /* lzop -c /tmp/plain.txt > /tmp/plain.lzo */
73 static const char lzo_compressed[] =
74 "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a\x10\x30\x20\x60\x09\x40\x01"
75 "\x05\x03\x00\x00\x09\x00\x00\x81\xb4\x52\x09\x54\xf1\x00\x00\x00"
76 "\x00\x09\x70\x6c\x61\x69\x6e\x2e\x74\x78\x74\x65\xb1\x07\x9c\x00"
77 "\x00\x01\x5e\x00\x00\x01\x0f\xc3\xc7\x7a\xe0\x00\x16\x49\x20\x61"
78 "\x6d\x20\x61\x20\x68\x69\x67\x68\x6c\x79\x20\x63\x6f\x6d\x70\x72"
79 "\x65\x73\x73\x61\x62\x6c\x65\x20\x62\x69\x74\x20\x6f\x66\x20\x74"
80 "\x65\x78\x74\x2e\x0a\x20\x2f\x9c\x00\x00\x22\x54\x68\x65\x72\x65"
81 "\x20\x61\x72\x65\x20\x6d\x61\x6e\x79\x20\x6c\x69\x6b\x65\x20\x6d"
82 "\x65\x2c\x20\x62\x75\x74\x20\x74\x68\x69\x73\x20\x6f\x6e\x65\x20"
83 "\x69\x73\x20\x6d\x69\x6e\x65\x2e\x0a\x49\x66\x20\x49\x20\x77\x84"
84 "\x06\x0a\x6e\x79\x20\x73\x68\x6f\x72\x74\x65\x72\x2c\x20\x74\x90"
85 "\x08\x00\x08\x77\x6f\x75\x6c\x64\x6e\x27\x74\x20\x62\x65\x20\x6d"
86 "\x75\x63\x68\x20\x73\x65\x6e\x73\x65\x20\x69\x6e\x0a\xf8\x19\x02"
87 "\x69\x6e\x67\x20\x6d\x64\x02\x64\x06\x00\x5a\x20\x66\x69\x72\x73"
88 "\x74\x20\x70\x6c\x61\x63\x65\x2e\x20\x41\x74\x20\x6c\x65\x61\x73"
89 "\x74\x20\x77\x69\x74\x68\x20\x6c\x7a\x6f\x2c\x20\x61\x6e\x79\x77"
90 "\x61\x79\x2c\x0a\x77\x68\x69\x63\x68\x20\x61\x70\x70\x65\x61\x72"
91 "\x73\x20\x74\x6f\x20\x62\x65\x68\x61\x76\x65\x20\x70\x6f\x6f\x72"
92 "\x6c\x79\x20\x69\x6e\x20\x74\x68\x65\x20\x66\x61\x63\x65\x20\x6f"
93 "\x66\x20\x73\x68\x6f\x72\x74\x20\x74\x65\x78\x74\x0a\x6d\x65\x73"
94 "\x73\x61\x67\x65\x73\x2e\x0a\x11\x00\x00\x00\x00\x00\x00";
95 static const unsigned long lzo_compressed_size = 334;
98 #define TEST_BUFFER_SIZE 512
100 typedef int (*mutate_func)(void *, unsigned long, void *, unsigned long,
103 static int compress_using_gzip(void *in, unsigned long in_size,
104 void *out, unsigned long out_max,
105 unsigned long *out_size)
108 unsigned long inout_size = out_max;
110 ret = gzip(out, &inout_size, in, in_size);
112 *out_size = inout_size;
117 static int uncompress_using_gzip(void *in, unsigned long in_size,
118 void *out, unsigned long out_max,
119 unsigned long *out_size)
122 unsigned long inout_size = in_size;
124 ret = gunzip(out, out_max, in, &inout_size);
126 *out_size = inout_size;
131 static int compress_using_bzip2(void *in, unsigned long in_size,
132 void *out, unsigned long out_max,
133 unsigned long *out_size)
135 /* There is no bzip2 compression in u-boot, so fake it. */
136 assert(in_size == strlen(plain));
137 assert(memcmp(plain, in, in_size) == 0);
139 if (bzip2_compressed_size > out_max)
142 memcpy(out, bzip2_compressed, bzip2_compressed_size);
144 *out_size = bzip2_compressed_size;
149 static int uncompress_using_bzip2(void *in, unsigned long in_size,
150 void *out, unsigned long out_max,
151 unsigned long *out_size)
154 unsigned int inout_size = out_max;
156 ret = BZ2_bzBuffToBuffDecompress(out, &inout_size, in, in_size,
157 CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);
159 *out_size = inout_size;
161 return (ret != BZ_OK);
164 static int compress_using_lzma(void *in, unsigned long in_size,
165 void *out, unsigned long out_max,
166 unsigned long *out_size)
168 /* There is no lzma compression in u-boot, so fake it. */
169 assert(in_size == strlen(plain));
170 assert(memcmp(plain, in, in_size) == 0);
172 if (lzma_compressed_size > out_max)
175 memcpy(out, lzma_compressed, lzma_compressed_size);
177 *out_size = lzma_compressed_size;
182 static int uncompress_using_lzma(void *in, unsigned long in_size,
183 void *out, unsigned long out_max,
184 unsigned long *out_size)
187 SizeT inout_size = out_max;
189 ret = lzmaBuffToBuffDecompress(out, &inout_size, in, in_size);
191 *out_size = inout_size;
193 return (ret != SZ_OK);
196 static int compress_using_lzo(void *in, unsigned long in_size,
197 void *out, unsigned long out_max,
198 unsigned long *out_size)
200 /* There is no lzo compression in u-boot, so fake it. */
201 assert(in_size == strlen(plain));
202 assert(memcmp(plain, in, in_size) == 0);
204 if (lzo_compressed_size > out_max)
207 memcpy(out, lzo_compressed, lzo_compressed_size);
209 *out_size = lzo_compressed_size;
214 static int uncompress_using_lzo(void *in, unsigned long in_size,
215 void *out, unsigned long out_max,
216 unsigned long *out_size)
219 size_t input_size = in_size;
220 size_t output_size = out_max;
222 ret = lzop_decompress(in, input_size, out, &output_size);
224 *out_size = output_size;
226 return (ret != LZO_E_OK);
229 #define errcheck(statement) if (!(statement)) { \
230 fprintf(stderr, "\tFailed: %s\n", #statement); \
235 static int run_test(char *name, mutate_func compress, mutate_func uncompress)
237 ulong orig_size, compressed_size, uncompressed_size;
239 void *compressed_buf = NULL;
240 void *uncompressed_buf = NULL;
241 void *compare_buf = NULL;
244 printf(" testing %s ...\n", name);
246 orig_buf = (void *)plain;
247 orig_size = strlen(orig_buf); /* Trailing NULL not included. */
248 errcheck(orig_size > 0);
250 compressed_size = uncompressed_size = TEST_BUFFER_SIZE;
251 compressed_buf = malloc(compressed_size);
252 errcheck(compressed_buf != NULL);
253 uncompressed_buf = malloc(uncompressed_size);
254 errcheck(uncompressed_buf != NULL);
255 compare_buf = malloc(uncompressed_size);
256 errcheck(compare_buf != NULL);
258 /* Compress works as expected. */
259 printf("\torig_size:%lu\n", orig_size);
260 memset(compressed_buf, 'A', TEST_BUFFER_SIZE);
261 errcheck(compress(orig_buf, orig_size,
262 compressed_buf, compressed_size,
263 &compressed_size) == 0);
264 printf("\tcompressed_size:%lu\n", compressed_size);
265 errcheck(compressed_size > 0);
266 errcheck(compressed_size < orig_size);
267 errcheck(((char *)compressed_buf)[compressed_size-1] != 'A');
268 errcheck(((char *)compressed_buf)[compressed_size] == 'A');
270 /* Uncompresses with space remaining. */
271 errcheck(uncompress(compressed_buf, compressed_size,
272 uncompressed_buf, uncompressed_size,
273 &uncompressed_size) == 0);
274 printf("\tuncompressed_size:%lu\n", uncompressed_size);
275 errcheck(uncompressed_size == orig_size);
276 errcheck(memcmp(orig_buf, uncompressed_buf, orig_size) == 0);
278 /* Uncompresses with exactly the right size output buffer. */
279 memset(uncompressed_buf, 'A', TEST_BUFFER_SIZE);
280 errcheck(uncompress(compressed_buf, compressed_size,
281 uncompressed_buf, orig_size,
282 &uncompressed_size) == 0);
283 errcheck(uncompressed_size == orig_size);
284 errcheck(memcmp(orig_buf, uncompressed_buf, orig_size) == 0);
285 errcheck(((char *)uncompressed_buf)[orig_size] == 'A');
287 /* Make sure compression does not over-run. */
288 memset(compare_buf, 'A', TEST_BUFFER_SIZE);
289 ret = compress(orig_buf, orig_size,
290 compare_buf, compressed_size - 1,
292 errcheck(((char *)compare_buf)[compressed_size] == 'A');
294 printf("\tcompress does not overrun\n");
296 /* Make sure decompression does not over-run. */
297 memset(compare_buf, 'A', TEST_BUFFER_SIZE);
298 ret = uncompress(compressed_buf, compressed_size,
299 compare_buf, uncompressed_size - 1,
301 errcheck(((char *)compare_buf)[uncompressed_size - 1] == 'A');
303 printf("\tuncompress does not overrun\n");
305 /* Got here, everything is fine. */
309 printf(" %s: %s\n", name, ret == 0 ? "ok" : "FAILED");
312 free(uncompressed_buf);
313 free(compressed_buf);
318 static int do_ut_compression(cmd_tbl_t *cmdtp, int flag, int argc,
323 err += run_test("gzip", compress_using_gzip, uncompress_using_gzip);
324 err += run_test("bzip2", compress_using_bzip2, uncompress_using_bzip2);
325 err += run_test("lzma", compress_using_lzma, uncompress_using_lzma);
326 err += run_test("lzo", compress_using_lzo, uncompress_using_lzo);
328 printf("ut_compression %s\n", err == 0 ? "ok" : "FAILED");
333 static int compress_using_none(void *in, unsigned long in_size,
334 void *out, unsigned long out_max,
335 unsigned long *out_size)
337 /* Here we just copy */
338 memcpy(out, in, in_size);
345 * run_bootm_test() - Run tests on the bootm decopmression function
347 * @comp_type: Compression type to test
348 * @compress: Our function to compress data
349 * @return 0 if OK, non-zero on failure
351 static int run_bootm_test(int comp_type, mutate_func compress)
353 ulong compress_size = 1024;
357 const ulong image_start = 0;
358 const ulong load_addr = 0x1000;
361 printf("Testing: %s\n", genimg_get_comp_name(comp_type));
362 compress_buff = map_sysmem(image_start, 0);
363 unc_len = strlen(plain);
364 compress((void *)plain, unc_len, compress_buff, compress_size,
366 err = bootm_decomp_image(comp_type, load_addr, image_start,
367 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
368 compress_buff, compress_size, unc_len,
372 err = bootm_decomp_image(comp_type, load_addr, image_start,
373 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
374 compress_buff, compress_size, unc_len - 1,
379 /* We can't detect corruption when not decompressing */
380 if (comp_type == IH_COMP_NONE)
382 memset(compress_buff + compress_size / 2, '\x49',
384 err = bootm_decomp_image(comp_type, load_addr, image_start,
385 IH_TYPE_KERNEL, map_sysmem(load_addr, 0),
386 compress_buff, compress_size, 0x10000,
394 static int do_ut_image_decomp(cmd_tbl_t *cmdtp, int flag, int argc,
399 err = run_bootm_test(IH_COMP_GZIP, compress_using_gzip);
400 err |= run_bootm_test(IH_COMP_BZIP2, compress_using_bzip2);
401 err |= run_bootm_test(IH_COMP_LZMA, compress_using_lzma);
402 err |= run_bootm_test(IH_COMP_LZO, compress_using_lzo);
403 err |= run_bootm_test(IH_COMP_NONE, compress_using_none);
405 printf("ut_image_decomp %s\n", err == 0 ? "ok" : "FAILED");
411 ut_compression, 5, 1, do_ut_compression,
412 "Basic test of compressors: gzip bzip2 lzma lzo", ""
416 ut_image_decomp, 5, 1, do_ut_image_decomp,
417 "Basic test of bootm decompression", ""