Skip to content

Commit 3ebe124

Browse files
Larhzutorvalds
authored andcommitted
decompressors: add boot-time XZ support
This implements the API defined in <linux/decompress/generic.h> which is used for kernel, initramfs, and initrd decompression. This patch together with the first patch is enough for XZ-compressed initramfs and initrd; XZ-compressed kernel will need arch-specific changes. The buffering requirements described in decompress_unxz.c are stricter than with gzip, so the relevant changes should be done to the arch-specific code when adding support for XZ-compressed kernel. Similarly, the heap size in arch-specific pre-boot code may need to be increased (30 KiB is enough). The XZ decompressor needs memmove(), memeq() (memcmp() == 0), and memzero() (memset(ptr, 0, size)), which aren't available in all arch-specific pre-boot environments. I'm including simple versions in decompress_unxz.c, but a cleaner solution would naturally be nicer. Signed-off-by: Lasse Collin <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Alain Knaff <[email protected]> Cc: Albin Tonnerre <[email protected]> Cc: Phillip Lougher <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 24fa040 commit 3ebe124

File tree

9 files changed

+469
-2
lines changed

9 files changed

+469
-2
lines changed

include/linux/decompress/unxz.h

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Wrapper for decompressing XZ-compressed kernel, initramfs, and initrd
3+
*
4+
* Author: Lasse Collin <[email protected]>
5+
*
6+
* This file has been put into the public domain.
7+
* You can do whatever you want with this file.
8+
*/
9+
10+
#ifndef DECOMPRESS_UNXZ_H
11+
#define DECOMPRESS_UNXZ_H
12+
13+
int unxz(unsigned char *in, int in_size,
14+
int (*fill)(void *dest, unsigned int size),
15+
int (*flush)(void *src, unsigned int size),
16+
unsigned char *out, int *in_used,
17+
void (*error)(char *x));
18+
19+
#endif

init/Kconfig

+19-1
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,16 @@ config HAVE_KERNEL_BZIP2
130130
config HAVE_KERNEL_LZMA
131131
bool
132132

133+
config HAVE_KERNEL_XZ
134+
bool
135+
133136
config HAVE_KERNEL_LZO
134137
bool
135138

136139
choice
137140
prompt "Kernel compression mode"
138141
default KERNEL_GZIP
139-
depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_LZO
142+
depends on HAVE_KERNEL_GZIP || HAVE_KERNEL_BZIP2 || HAVE_KERNEL_LZMA || HAVE_KERNEL_XZ || HAVE_KERNEL_LZO
140143
help
141144
The linux kernel is a kind of self-extracting executable.
142145
Several compression algorithms are available, which differ
@@ -181,6 +184,21 @@ config KERNEL_LZMA
181184
two. Compression is slowest. The kernel size is about 33%
182185
smaller with LZMA in comparison to gzip.
183186

187+
config KERNEL_XZ
188+
bool "XZ"
189+
depends on HAVE_KERNEL_XZ
190+
help
191+
XZ uses the LZMA2 algorithm and instruction set specific
192+
BCJ filters which can improve compression ratio of executable
193+
code. The size of the kernel is about 30% smaller with XZ in
194+
comparison to gzip. On architectures for which there is a BCJ
195+
filter (i386, x86_64, ARM, IA-64, PowerPC, and SPARC), XZ
196+
will create a few percent smaller kernel than plain LZMA.
197+
198+
The speed is about the same as with LZMA: The decompression
199+
speed of XZ is better than that of bzip2 but worse than gzip
200+
and LZO. Compression is slow.
201+
184202
config KERNEL_LZO
185203
bool "LZO"
186204
depends on HAVE_KERNEL_LZO

lib/Kconfig

+4
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ config DECOMPRESS_BZIP2
122122
config DECOMPRESS_LZMA
123123
tristate
124124

125+
config DECOMPRESS_XZ
126+
select XZ_DEC
127+
tristate
128+
125129
config DECOMPRESS_LZO
126130
select LZO_DECOMPRESS
127131
tristate

lib/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ obj-$(CONFIG_RAID6_PQ) += raid6/
7575
lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
7676
lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
7777
lib-$(CONFIG_DECOMPRESS_LZMA) += decompress_unlzma.o
78+
lib-$(CONFIG_DECOMPRESS_XZ) += decompress_unxz.o
7879
lib-$(CONFIG_DECOMPRESS_LZO) += decompress_unlzo.o
7980

8081
obj-$(CONFIG_TEXTSEARCH) += textsearch.o

lib/decompress.c

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include <linux/decompress/bunzip2.h>
1010
#include <linux/decompress/unlzma.h>
11+
#include <linux/decompress/unxz.h>
1112
#include <linux/decompress/inflate.h>
1213
#include <linux/decompress/unlzo.h>
1314

@@ -23,6 +24,9 @@
2324
#ifndef CONFIG_DECOMPRESS_LZMA
2425
# define unlzma NULL
2526
#endif
27+
#ifndef CONFIG_DECOMPRESS_XZ
28+
# define unxz NULL
29+
#endif
2630
#ifndef CONFIG_DECOMPRESS_LZO
2731
# define unlzo NULL
2832
#endif
@@ -36,6 +40,7 @@ static const struct compress_format {
3640
{ {037, 0236}, "gzip", gunzip },
3741
{ {0x42, 0x5a}, "bzip2", bunzip2 },
3842
{ {0x5d, 0x00}, "lzma", unlzma },
43+
{ {0xfd, 0x37}, "xz", unxz },
3944
{ {0x89, 0x4c}, "lzo", unlzo },
4045
{ {0, 0}, NULL, NULL }
4146
};

0 commit comments

Comments
 (0)