aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/decompress/unlz4.h10
-rw-r--r--init/Kconfig17
-rw-r--r--lib/Kconfig7
-rw-r--r--lib/Makefile2
-rw-r--r--lib/decompress.c5
-rw-r--r--lib/decompress_unlz4.c187
-rw-r--r--lib/lz4/Makefile1
-rw-r--r--lib/lz4/lz4_decompress.c2
-rw-r--r--scripts/Makefile.lib5
-rw-r--r--usr/Kconfig9
10 files changed, 243 insertions, 2 deletions
diff --git a/include/linux/decompress/unlz4.h b/include/linux/decompress/unlz4.h
new file mode 100644
index 000000000000..d5b68bf3ec92
--- /dev/null
+++ b/include/linux/decompress/unlz4.h
@@ -0,0 +1,10 @@
1#ifndef DECOMPRESS_UNLZ4_H
2#define DECOMPRESS_UNLZ4_H
3
4int unlz4(unsigned char *inbuf, int len,
5 int(*fill)(void*, unsigned int),
6 int(*flush)(void*, unsigned int),
7 unsigned char *output,
8 int *pos,
9 void(*error)(char *x));
10#endif
diff --git a/init/Kconfig b/init/Kconfig
index ea1be003275a..54d3fa5ae723 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -112,10 +112,13 @@ config HAVE_KERNEL_XZ
112config HAVE_KERNEL_LZO 112config HAVE_KERNEL_LZO
113 bool 113 bool
114 114
115config HAVE_KERNEL_LZ4
116 bool
117
115choice 118choice
116 prompt "Kernel compression mode" 119 prompt "Kernel compression mode"
117 default KERNEL_GZIP 120 default KERNEL_GZIP
118 depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_XZ || HAVE_KERNEL_LZO 121 depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_XZ || HAVE_KERNEL_LZO || HAVE_KERNEL_LZ4
119 help 122 help
120 The linux kernel is a kind of self-extracting executable. 123 The linux kernel is a kind of self-extracting executable.
121 Several compression algorithms are available, which differ 124 Several compression algorithms are available, which differ
@@ -182,6 +185,18 @@ config KERNEL_LZO
182 size is about 10% bigger than gzip; however its speed 185 size is about 10% bigger than gzip; however its speed
183 (both compression and decompression) is the fastest. 186 (both compression and decompression) is the fastest.
184 187
188config KERNEL_LZ4
189 bool "LZ4"
190 depends on HAVE_KERNEL_LZ4
191 help
192 LZ4 is an LZ77-type compressor with a fixed, byte-oriented encoding.
193 A preliminary version of LZ4 de/compression tool is available at
194 <https://code.google.com/p/lz4/>.
195
196 Its compression ratio is worse than LZO. The size of the kernel
197 is about 8% bigger than LZO. But the decompression speed is
198 faster than LZO.
199
185endchoice 200endchoice
186 201
187config DEFAULT_HOSTNAME 202config DEFAULT_HOSTNAME
diff --git a/lib/Kconfig b/lib/Kconfig
index f1ed53c3aa44..e9cdc8ffdcee 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -194,6 +194,9 @@ config LZO_COMPRESS
194config LZO_DECOMPRESS 194config LZO_DECOMPRESS
195 tristate 195 tristate
196 196
197config LZ4_DECOMPRESS
198 tristate
199
197source "lib/xz/Kconfig" 200source "lib/xz/Kconfig"
198 201
199# 202#
@@ -218,6 +221,10 @@ config DECOMPRESS_LZO
218 select LZO_DECOMPRESS 221 select LZO_DECOMPRESS
219 tristate 222 tristate
220 223
224config DECOMPRESS_LZ4
225 select LZ4_DECOMPRESS
226 tristate
227
221# 228#
222# Generic allocator support is selected if needed 229# Generic allocator support is selected if needed
223# 230#
diff --git a/lib/Makefile b/lib/Makefile
index 9afb4f745e8f..326f6c7e6db1 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -75,6 +75,7 @@ obj-$(CONFIG_REED_SOLOMON) += reed_solomon/
75obj-$(CONFIG_BCH) += bch.o 75obj-$(CONFIG_BCH) += bch.o
76obj-$(CONFIG_LZO_COMPRESS) += lzo/ 76obj-$(CONFIG_LZO_COMPRESS) += lzo/
77obj-$(CONFIG_LZO_DECOMPRESS) += lzo/ 77obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
78obj-$(CONFIG_LZ4_DECOMPRESS) += lz4/
78obj-$(CONFIG_XZ_DEC) += xz/ 79obj-$(CONFIG_XZ_DEC) += xz/
79obj-$(CONFIG_RAID6_PQ) += raid6/ 80obj-$(CONFIG_RAID6_PQ) += raid6/
80 81
@@ -83,6 +84,7 @@ lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
83lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o 84lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o
84lib-$(CONFIG_DECOMPRESS_XZ) += decompress_unxz.o 85lib-$(CONFIG_DECOMPRESS_XZ) += decompress_unxz.o
85lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o 86lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o
87lib-$(CONFIG_DECOMPRESS_LZ4) += decompress_unlz4.o
86 88
87obj-$(CONFIG_TEXTSEARCH) += textsearch.o 89obj-$(CONFIG_TEXTSEARCH) += textsearch.o
88obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o 90obj-$(CONFIG_TEXTSEARCH_KMP) += ts_kmp.o
diff --git a/lib/decompress.c b/lib/decompress.c
index f8fdedaf7b3d..4d1cd0397aab 100644
--- a/lib/decompress.c
+++ b/lib/decompress.c
@@ -11,6 +11,7 @@
11#include <linux/decompress/unxz.h> 11#include <linux/decompress/unxz.h>
12#include <linux/decompress/inflate.h> 12#include <linux/decompress/inflate.h>
13#include <linux/decompress/unlzo.h> 13#include <linux/decompress/unlzo.h>
14#include <linux/decompress/unlz4.h>
14 15
15#include <linux/types.h> 16#include <linux/types.h>
16#include <linux/string.h> 17#include <linux/string.h>
@@ -31,6 +32,9 @@
31#ifndef CONFIG_DECOMPRESS_LZO 32#ifndef CONFIG_DECOMPRESS_LZO
32# define unlzo NULL 33# define unlzo NULL
33#endif 34#endif
35#ifndef CONFIG_DECOMPRESS_LZ4
36# define unlz4 NULL
37#endif
34 38
35struct compress_format { 39struct compress_format {
36 unsigned char magic[2]; 40 unsigned char magic[2];
@@ -45,6 +49,7 @@ static const struct compress_format compressed_formats[] __initconst = {
45 { {0x5d, 0x00}, "lzma", unlzma }, 49 { {0x5d, 0x00}, "lzma", unlzma },
46 { {0xfd, 0x37}, "xz", unxz }, 50 { {0xfd, 0x37}, "xz", unxz },
47 { {0x89, 0x4c}, "lzo", unlzo }, 51 { {0x89, 0x4c}, "lzo", unlzo },
52 { {0x02, 0x21}, "lz4", unlz4 },
48 { {0, 0}, NULL, NULL } 53 { {0, 0}, NULL, NULL }
49}; 54};
50 55
diff --git a/lib/decompress_unlz4.c b/lib/decompress_unlz4.c
new file mode 100644
index 000000000000..3e67cfad16ad
--- /dev/null
+++ b/lib/decompress_unlz4.c
@@ -0,0 +1,187 @@
1/*
2 * Wrapper for decompressing LZ4-compressed kernel, initramfs, and initrd
3 *
4 * Copyright (C) 2013, LG Electronics, Kyungsik Lee <kyungsik.lee@lge.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifdef STATIC
12#define PREBOOT
13#include "lz4/lz4_decompress.c"
14#else
15#include <linux/decompress/unlz4.h>
16#endif
17#include <linux/types.h>
18#include <linux/lz4.h>
19#include <linux/decompress/mm.h>
20#include <linux/compiler.h>
21
22#include <asm/unaligned.h>
23
24/*
25 * Note: Uncompressed chunk size is used in the compressor side
26 * (userspace side for compression).
27 * It is hardcoded because there is not proper way to extract it
28 * from the binary stream which is generated by the preliminary
29 * version of LZ4 tool so far.
30 */
31#define LZ4_DEFAULT_UNCOMPRESSED_CHUNK_SIZE (8 << 20)
32#define ARCHIVE_MAGICNUMBER 0x184C2102
33
34STATIC inline int INIT unlz4(u8 *input, int in_len,
35 int (*fill) (void *, unsigned int),
36 int (*flush) (void *, unsigned int),
37 u8 *output, int *posp,
38 void (*error) (char *x))
39{
40 int ret = -1;
41 size_t chunksize = 0;
42 size_t uncomp_chunksize = LZ4_DEFAULT_UNCOMPRESSED_CHUNK_SIZE;
43 u8 *inp;
44 u8 *inp_start;
45 u8 *outp;
46 int size = in_len;
47#ifdef PREBOOT
48 size_t out_len = get_unaligned_le32(input + in_len);
49#endif
50 size_t dest_len;
51
52
53 if (output) {
54 outp = output;
55 } else if (!flush) {
56 error("NULL output pointer and no flush function provided");
57 goto exit_0;
58 } else {
59 outp = large_malloc(uncomp_chunksize);
60 if (!outp) {
61 error("Could not allocate output buffer");
62 goto exit_0;
63 }
64 }
65
66 if (input && fill) {
67 error("Both input pointer and fill function provided,");
68 goto exit_1;
69 } else if (input) {
70 inp = input;
71 } else if (!fill) {
72 error("NULL input pointer and missing fill function");
73 goto exit_1;
74 } else {
75 inp = large_malloc(lz4_compressbound(uncomp_chunksize));
76 if (!inp) {
77 error("Could not allocate input buffer");
78 goto exit_1;
79 }
80 }
81 inp_start = inp;
82
83 if (posp)
84 *posp = 0;
85
86 if (fill)
87 fill(inp, 4);
88
89 chunksize = get_unaligned_le32(inp);
90 if (chunksize == ARCHIVE_MAGICNUMBER) {
91 inp += 4;
92 size -= 4;
93 } else {
94 error("invalid header");
95 goto exit_2;
96 }
97
98 if (posp)
99 *posp += 4;
100
101 for (;;) {
102
103 if (fill)
104 fill(inp, 4);
105
106 chunksize = get_unaligned_le32(inp);
107 if (chunksize == ARCHIVE_MAGICNUMBER) {
108 inp += 4;
109 size -= 4;
110 if (posp)
111 *posp += 4;
112 continue;
113 }
114 inp += 4;
115 size -= 4;
116
117 if (posp)
118 *posp += 4;
119
120 if (fill) {
121 if (chunksize > lz4_compressbound(uncomp_chunksize)) {
122 error("chunk length is longer than allocated");
123 goto exit_2;
124 }
125 fill(inp, chunksize);
126 }
127#ifdef PREBOOT
128 if (out_len >= uncomp_chunksize) {
129 dest_len = uncomp_chunksize;
130 out_len -= dest_len;
131 } else
132 dest_len = out_len;
133 ret = lz4_decompress(inp, &chunksize, outp, dest_len);
134#else
135 dest_len = uncomp_chunksize;
136 ret = lz4_decompress_unknownoutputsize(inp, chunksize, outp,
137 &dest_len);
138#endif
139 if (ret < 0) {
140 error("Decoding failed");
141 goto exit_2;
142 }
143
144 if (flush && flush(outp, dest_len) != dest_len)
145 goto exit_2;
146 if (output)
147 outp += dest_len;
148 if (posp)
149 *posp += chunksize;
150
151 size -= chunksize;
152
153 if (size == 0)
154 break;
155 else if (size < 0) {
156 error("data corrupted");
157 goto exit_2;
158 }
159
160 inp += chunksize;
161 if (fill)
162 inp = inp_start;
163 }
164
165 ret = 0;
166exit_2:
167 if (!input)
168 large_free(inp_start);
169exit_1:
170 if (!output)
171 large_free(outp);
172exit_0:
173 return ret;
174}
175
176#ifdef PREBOOT
177STATIC int INIT decompress(unsigned char *buf, int in_len,
178 int(*fill)(void*, unsigned int),
179 int(*flush)(void*, unsigned int),
180 unsigned char *output,
181 int *posp,
182 void(*error)(char *x)
183 )
184{
185 return unlz4(buf, in_len - 4, fill, flush, output, posp, error);
186}
187#endif
diff --git a/lib/lz4/Makefile b/lib/lz4/Makefile
new file mode 100644
index 000000000000..7f548c6d1c5c
--- /dev/null
+++ b/lib/lz4/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_LZ4_DECOMPRESS) += lz4_decompress.o
diff --git a/lib/lz4/lz4_decompress.c b/lib/lz4/lz4_decompress.c
index dcc89753af65..d3414eae73a1 100644
--- a/lib/lz4/lz4_decompress.c
+++ b/lib/lz4/lz4_decompress.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * LZ4 Decompressor for Linux kernel 2 * LZ4 Decompressor for Linux kernel
3 * 3 *
4 * Copyright (C) 2013 LG Electronics Co., Ltd. (http://www.lge.com/) 4 * Copyright (C) 2013, LG Electronics, Kyungsik Lee <kyungsik.lee@lge.com>
5 * 5 *
6 * Based on LZ4 implementation by Yann Collet. 6 * Based on LZ4 implementation by Yann Collet.
7 * 7 *
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index f97869f1f09b..6031e2380638 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -311,6 +311,11 @@ cmd_lzo = (cat $(filter-out FORCE,$^) | \
311 lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \ 311 lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
312 (rm -f $@ ; false) 312 (rm -f $@ ; false)
313 313
314quiet_cmd_lz4 = LZ4 $@
315cmd_lz4 = (cat $(filter-out FORCE,$^) | \
316 lz4c -l -c1 stdin stdout && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
317 (rm -f $@ ; false)
318
314# U-Boot mkimage 319# U-Boot mkimage
315# --------------------------------------------------------------------------- 320# ---------------------------------------------------------------------------
316 321
diff --git a/usr/Kconfig b/usr/Kconfig
index 085872bb2bb5..642f503d3e9f 100644
--- a/usr/Kconfig
+++ b/usr/Kconfig
@@ -90,6 +90,15 @@ config RD_LZO
90 Support loading of a LZO encoded initial ramdisk or cpio buffer 90 Support loading of a LZO encoded initial ramdisk or cpio buffer
91 If unsure, say N. 91 If unsure, say N.
92 92
93config RD_LZ4
94 bool "Support initial ramdisks compressed using LZ4" if EXPERT
95 default !EXPERT
96 depends on BLK_DEV_INITRD
97 select DECOMPRESS_LZ4
98 help
99 Support loading of a LZ4 encoded initial ramdisk or cpio buffer
100 If unsure, say N.
101
93choice 102choice
94 prompt "Built-in initramfs compression mode" if INITRAMFS_SOURCE!="" 103 prompt "Built-in initramfs compression mode" if INITRAMFS_SOURCE!=""
95 help 104 help